Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Embedding IO<br />
As mentioned before, effects are first class values in <strong>Haskell</strong>.<br />
In <strong>Haskell</strong> we don’t read from a file directly, but create a value that represents reading from a file. is<br />
allows us to very cleanly model an interpreter for our language inside of <strong>Haskell</strong> by establishing a mapping<br />
between the base operations of our language and existing function implementations of the standard<br />
operations in <strong>Haskell</strong>, and using monadic operations to build up a pure effectful computation as a result<br />
of interpretation. After evaluation, we finally lift the resulting IO value into <strong>Haskell</strong> and execute the<br />
results. is fits in nicely with the PHOAS model and allows us to efficiently implement a fully-fledged<br />
interpreter for our language with remarkably little code, simply by exploiting <strong>Haskell</strong>’s implementation.<br />
To embed IO actions inside of our interpreter we create a distinct VEffect value that will build up a<br />
sequenced IO computation during evaluation. is value will be passed off to <strong>Haskell</strong> and reified into<br />
real world effects.<br />
data ExprP a<br />
= VarP a<br />
| GlobalP Name<br />
| AppP (ExprP a) (ExprP a)<br />
| LamP (a -> ExprP a)<br />
| LitP Char<br />
| EffectP a<br />
data Value<br />
= VChar Char<br />
| VFun (Value -> Value)<br />
| VEffect (IO Value)<br />
| VUnit<br />
fromVEff :: Value -> (IO Value)<br />
fromVEff val = case val of<br />
VEffect f -> f<br />
_<br />
-> error ”not an effect”<br />
eval :: Expr -> Value<br />
eval e = ev (unExpr e) where<br />
ev (LamP f) = VFun(ev . f)<br />
ev (AppP e1 e2) = fromVFun (ev e1) (ev e2)<br />
ev (LitP n) = VChar n<br />
ev (EffectP v) = v<br />
ev (VarP v) = v<br />
ev (GlobalP op) = prim op<br />
-- Lift an effect from our language into <strong>Haskell</strong> IO.<br />
run :: Expr -> IO ()<br />
run f = void (fromVEff (eval f))<br />
76