我正在通过令人惊叹的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',粗略地说。 –