mirror of
https://github.com/thma/LtuPatternFactory.git
synced 2024-12-12 10:42:08 +03:00
wip
This commit is contained in:
parent
704eeeaf0b
commit
8757a649e8
36
README.md
36
README.md
@ -777,12 +777,46 @@ Next we define an evaluator function that pattern matches the above expression A
|
||||
|
||||
```haskell
|
||||
eval :: MonadReader (Env a) m => Exp a -> m a
|
||||
eval (Var x) = asks (fetch x)
|
||||
eval (Val i) = return i
|
||||
eval (Var x) = asks (fetch x)
|
||||
eval (BinOp op e1 e2) = liftM2 op (eval e1) (eval e2)
|
||||
eval (Let x e1 e2) = eval e1 >>= \v -> local ((x,v):) (eval e2)
|
||||
```
|
||||
|
||||
Let's explore this dense code line by line.
|
||||
|
||||
```haskell
|
||||
eval :: MonadReader (Env a) m => Exp a -> m a
|
||||
```
|
||||
|
||||
The most simple instance for `MonadReader` is the partially applied function type `((->) env)`.
|
||||
Let's assume the compiler will choose this type as the `MonadReader` instance. We can then rewrite the function signature as follows:
|
||||
|
||||
```haskell
|
||||
eval :: Exp a -> ((->) (Env a)) a -- expanding m to ((->) (Env a))
|
||||
eval :: Exp a -> Env a -> a -- applying infix notation for (->)
|
||||
```
|
||||
|
||||
This is exactly the signature we were using for the `Applicative` eval function which matches our original intent to eval an expression of type `Exp a` in an environment of type `Env a` to a result of type `a`.
|
||||
|
||||
```haskell
|
||||
eval (Val i) = return i
|
||||
```
|
||||
|
||||
In this line we are pattern matching for a `(Val i)`. The atomic value `i` is `return`ed, that is lifted to a value of the type `Env a -> a`.
|
||||
|
||||
```haskell
|
||||
eval (Var x) = asks (fetch x)
|
||||
```
|
||||
|
||||
`asks` is a helper function that applies its argument `f :: env -> a` (in our case `(fetch x)` that is lookup of variable `x`) to the environment. It's thus typically used to handle environment lookups:
|
||||
|
||||
```haskell
|
||||
asks :: (MonadReader env m) => (env -> a) -> m a
|
||||
asks f = ask >>= return . f
|
||||
```
|
||||
|
||||
|
||||
[to be continued]
|
||||
|
||||
This section was inspired by ideas presented in [Quick Interpreters with the Reader Monad](https://donsbot.wordpress.com/2006/12/11/quick-interpreters-with-the-reader-monad/).
|
||||
|
@ -14,9 +14,12 @@ type BinOperator a = a -> a -> a
|
||||
type Env a = [(String, a)]
|
||||
|
||||
-- using a Reader Monad to thread the environment. The Environment can be accessed by ask and asks.
|
||||
--eval :: Exp a => Exp a -> Env a -> a
|
||||
eval :: MonadReader (Env a) m => Exp a -> m a
|
||||
eval (Var x) = asks (fetch x)
|
||||
--eval :: Exp a -> Env a -> a
|
||||
eval :: Exp a -> ((->) (Env a)) a
|
||||
--eval :: MonadReader (Env a) m => Exp a -> m a
|
||||
-- Exp a -> ((->) Env a) a
|
||||
-- Exp a -> Env a -> a
|
||||
eval (Var x) = ask >>= return . (fetch x) --asks (fetch x)
|
||||
eval (Val i) = return i
|
||||
eval (BinOp op e1 e2) = liftM2 op (eval e1) (eval e2)
|
||||
eval (Let x e1 e2) = eval e1 >>= \v -> local ((x,v):) (eval e2)
|
||||
@ -46,7 +49,7 @@ interpreterDemo = do
|
||||
(BinOp (*) (Var "pi") (Var "x"))
|
||||
env = [("pi", pi)]
|
||||
print $ eval exp env
|
||||
print $ runReader (eval exp) env
|
||||
--print $ runReader (eval exp) env
|
||||
|
||||
print $ evalState (eval1 exp) env
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user