- Write a term once, evaluate many times (with different orders)
- Embedding of the DSL into Haskell
- Call-by-name
- Call-by-value
- The only difference is the interpretation of lam:
- before evaluating the body, _always_ evaluate the argument
- Call-by-need
- The only difference is the interpretation of lam:
- before evaluating the body, share the argument
- The argument is evaluated _at most_ once

- Almost Haskell98. See CB98,hs for the genuine Haskell98 version Here we use a few extensions to make the code prettier
- Embedding a higher-order domain-specific language (simply-typed * lambda-calculus with constants) with a selectable evaluation order: * Call-by-value, call-by-name, call-by-need

- type Arr exp a b = exp a -> exp b
- class EDSL exp where
- let_ :: EDSL exp => exp a -> (exp a -> exp b) -> exp b
- t :: EDSL exp => exp Int
- newtype S l m a = S {
- unS :: m a

- data Name
- runName :: S Name m a -> m a
- t1 :: EDSL exp => exp Int
- t2 :: EDSL exp => exp Int
- data Value
- vn :: S Value m x -> S Name m x
- nv :: S Name m x -> S Value m x
- runValue :: S Value m a -> m a
- share :: MonadIO m => m a -> m (m a)
- data Lazy
- ln :: S Lazy m x -> S Name m x
- nl :: S Name m x -> S Lazy m x
- runLazy :: S Lazy m a -> m a

# Documentation

let_ :: EDSL exp => exp a -> (exp a -> exp b) -> exp bSource

A convenient abbreviation (could've been called `bind`

)