「Write Yourself a Scheme in 48 Hours」 を写経してみる(9) : 変数の追加と割り当ての中で define, set!で変数が定義、変更される様子を覗きたかったのですが、IORef が入れ子になっていて簡単には覗けません。そこで、IORefの練習に表示する関数を作ってみました。
type Env = IORef [(String, IORef LispVal)] -- これが定義されている型 showEnv :: IORef [(String, IORef LispVal)] -> IO [(String, LispVal)] showEnv envRef = readIORef envRef >>= flip readLS [] where readLS :: [(String, IORef LispVal)] -> [(String, LispVal)] -> IO [(String, LispVal)] readLS [] out = return out readLS (x:xs) out = readTuple x >>= \tuple -> readLS xs (tuple:out) readTuple :: (String, IORef LispVal) -> IO (String, LispVal) readTuple tuple = readIORef (snd tuple)>>= \val -> return (fst tuple,val)
それではやってみます。
> env <- nullEnv -- 変数を保存する環境を初期化 > evalString env "(define x 3)" -- x に 3を定義 defineVar: "x" : Number 3 "Number 3" > evalString env "(define y 99)" defineVar: "y" : Number 99 "Number 99" > showEnv env [("x",Number 3),("y",Number 99)] -- 変数を表示してみる。 > evalString env "(set! y 0)" setVar: "y" : Number 0 "Number 0" > showEnv env [("x",Number 3),("y",Number 0)] > evalString env "(define list '(a 2 3))" defineVar: "list" : List [Atom "a",Number 2,Number 3] "List [Atom \"a\",Number 2,Number 3]" > showEnv env [("x",Number 3),("y",Number 0),("list",List [Atom "a",Number 2,Number 3])]
日本語版「48時間でSchemeを書こう」がありました・・・。良く見ろよ→オレ。