content: {-# LANGUAGE QuasiQuotes #-}
  
  
  -- | Common Haskell functions, translated to STG. Use the 'Monoid' instance
  -- for 'Program' to mix them.
  --
  -- This module should be imported qualified to avoid clashes with standard
  -- Haskell definitions.
  module Stg.Prelude (
      module Stg.Prelude,
      module Stg.Prelude.Bool,
      module Stg.Prelude.Function,
      module Stg.Prelude.List,
      module Stg.Prelude.Maybe,
      module Stg.Prelude.Number,
      module Stg.Prelude.Tuple,
  ) where
  
  
  
  import Prelude ()
  
  import Stg.Language
  import Stg.Parser.QuasiQuoter
  import Stg.Prelude.Bool
  import Stg.Prelude.Function
  import Stg.Prelude.List
  import Stg.Prelude.Maybe
  import Stg.Prelude.Number
  import Stg.Prelude.Tuple
  
  {-# ANN module "HLint: ignore Use import/export shortcut" #-}
      -- Haddock doesn't like this trick :-/
  
  
  
  -- | Force a value to normal form and return it.
  --
  -- This function makes heavy use of the fact that the STG is untyped. It
  -- currently supports the following types:
  --
  --  * Unit (Unit)
  --  * Maybe (Just, Nothing)
  --  * Bool (True, False)
  --  * Int (Int#)
  --  * Either (Left, Right)
  --  * Tuples (Pair, Triple)
  --  * List (Nil, Cons)
  --
  -- Everything else will run into an error.
  force :: Program
  force = [stg|
      force = \ =>
          letrec
              go0 = \ -> Done;
              go1 = \(go go0) x     -> case go x of default -> go0;
              go2 = \(go go1) x y   -> case go x of default -> go1 y;
              go3 = \(go go2) x y z -> case go x of default -> go2 y z;
  
              go = \(go0 go1 go2 go3) x -> case x of
  
                  Unit -> go0;
  
                  Nothing -> go0;
                  Just x  -> go1 x;
  
                  True  -> go0;
                  False -> go0;
  
                  Int# _ -> go0;
  
                  Left l  -> go1 l;
                  Right r -> go1 r;
  
                  Pair   x y   -> go2 x y;
                  Triple x y z -> go3 x y z;
  
                  Nil       -> go0;
                  Cons x xs -> go2 x xs;
  
                  x -> Error_ForceNotImplementedFor x;
  
              forceAndReturnValue = \(go) x -> case go x of default -> x
          in forceAndReturnValue |]
  