Readerモナドを試してみる
30分プログラム、その663。Readerモナドを試してみました。
The Reader monadを読んでたら、環境がどうのこうの書いてあったので、簡単なプログラミング言語を作ってみました。環境が使いたかっただけなので、変数束縛と変数参照のほかには、整数リテラルと加算演算子ぐらいしかありません。
前に読んだHaskellの入門書には「複数の関数で引数を共有したいときはReaderモナドを使うといいよー」と書いてあったけど、微妙に違う気がする。共有できるのは引数一個だけだし、共有してる変数を書き換えることもできるし。
使い方
*Main> runEval $ Int 40 `Add` Int 2 42 *Main> runEval $ Let ("x",Int 1) $ Int 4 `Add` Var "x" 5
ソースコード
import Control.Monad.Reader data Expr = Let (String,Expr) Expr | Var String | Int Int | Expr `Add` Expr deriving Show type Env = [(String,Int)] eval :: Expr -> Reader Env Int eval (Int n) = return n eval (Add lhs rhs) = do x <- eval lhs y <- eval rhs return $ x + y eval (Var name) = do val <- asks $ lookup name return $ case val of Just x -> x Nothing -> 0 eval (Let (name,value) body) = do value' <- eval value local ((name,value'):) $ eval body runEval e = runReader (eval e) []