You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
e prim function will simply perform a lookup on the set of builtin operations, which we’ll define with<br />
a bit of syntactic sugar for wrapping up <strong>Haskell</strong> functions.<br />
unary :: (Value -> Value) -> Value<br />
unary f = lam $ \a -> f a<br />
binary :: (Value -> Value -> Value) -> Value<br />
binary f = lam $ \a -><br />
lam $ \b -> f a b<br />
prim :: Name -> Value<br />
prim op = case op of<br />
”putChar#” -> unary $ \x -><br />
VEffect $ do<br />
putChar (fromVChar x)<br />
return VUnit<br />
”getChar#” -> VEffect $ do<br />
val binary $ \x y -> bindIO x y<br />
”returnIO#” -> unary $ \x -> returnIO x<br />
”thenIO#” -> binary $ \x y -> thenIO x y<br />
For example thenIO# sequences effects in our language will simply squash two VEffect objects into<br />
one composite effect building up a new VEffect value that is using <strong>Haskell</strong>’s monadic sequencing on<br />
the internal IO value.<br />
bindIO :: Value -> Value -> Value<br />
bindIO (VEffect f) (VFun g) = VEffect (f >>= fromVEff . g)<br />
thenIO :: Value -> Value -> Value<br />
thenIO (VEffect f) (VEffect g) = VEffect (f >> g)<br />
returnIO :: Value -> Value<br />
returnIO a = VEffect $ return a<br />
Effectively we’re just recreating the same conceptual relationship that <strong>Haskell</strong> IO has with its runtime,<br />
but instead our host language uses <strong>Haskell</strong> as the runtime!<br />
Full Source<br />
Evaluation<br />
77