25.10.2015 Views

Write You a Haskell Stephen Diehl

1kEcQTb

1kEcQTb

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!