我正在通過令人驚歎的Write Yourself a Scheme in 48 Hours工作,並完成了核心任務並想擴展它,但遇到了問題。我想要做的是讓eval
函數可用於運行時,但有問題將其存儲到全局環境中。在Haskell中獲取元素輸出IO
的運行時環境的類型是:
type Env = IORef [(String, IORef LispVal)]
Haskell的eval
實現類型:
eval :: Env -> LispVal -> IOThrowsError LispVal
全球環境類型的映射:
primitiveBindings :: IO Env
爲它包含執行IO與純函數混合的函數。我的嘗試是運行eval
設置爲主機eval
部分與地球環境類似這樣的應用:
baseFun :: [(String, [LispVal] -> IOThrowsError LispVal)]
baseFun = [("eval", unaryOp (eval (liftIO $ readIORef primitiveBindings)))]
其中unaryOp
是:
unaryOp :: (LispVal -> ThrowsError LispVal) -> [LispVal] -> ThrowsError LispVal
unaryOp f [v] = f v
我想那麼元素加入到全球環境,但我得到的編譯錯誤:
Couldn't match expected type `IORef a'
against inferred type `IO Env'
In the first argument of `readIORef', namely `primitiveBindings'
In the second argument of `($)', namely `readIORef primitiveBindings'
In the first argument of `eval', namely
`(liftIO $ readIORef primitiveBindings)'
它似乎的readIORef env
這種模式發生Ø在代碼中,因此它不清楚爲什麼它不在這裏工作。我非常感謝我的錯誤啓發。作爲參考,我的代碼幾乎完全像final code for the original tutorial作爲參考。
謝謝
如果你澄清了'ThrowsError'和'IOThrowsError'之間的關係,這將會很有用。我去看看它,看起來像'ThrowsError'是''LispError''和'IOThrowsError'''ErrorT LispError IO',粗略地說。 –