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 in the same Final Tagless framework This is the Haskell98 version of the code CB.hs located in the same directory as this file
http://okmij.org/ftp/tagless-final/tagless-typed.html#call-by-any
- 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 SName m a = SN {
- unSN :: m a
- runName :: SName m a -> m a
- t1 :: EDSL exp => exp Int
- t2 :: EDSL exp => exp Int
- newtype SValue m a = SV {
- unSV :: m a
- vn :: SValue m x -> SName m x
- nv :: SName m x -> SValue m x
- runValue :: SValue m a -> m a
- share :: MonadIO m => m a -> m (m a)
- newtype SLazy m a = SL {
- unSL :: m a
- ln :: SLazy m x -> SName m x
- nl :: SName m x -> SLazy m x
- runLazy :: SLazy m a -> m a
Documentation
Interpretation of EDSL expressions as values of the host language (Haskell) An EDSL expression of type a is interpreted as a Haskell value of the type SName m a, SValue m a or SLazy m a, where m is a Monad (the parameter of the interpretation).
t1 :: EDSL exp => exp IntSource
The addition (x add
x) is performed twice because y is bound
to a computation, and y is evaluated twice
A more elaborate example
The result of subtraction was not needed, and so it was not performed
OTH, (int 5 add
int 5) was computed four times
Call-by-value
share :: MonadIO m => m a -> m (m a)Source
We now evaluate the previously written tests t, t1, t2 under the new interpretation
Call-by-need