stgi-1.1: src/Stg/Prelude.hs
{-# 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 |]