我正在完成令人惊叹的“在 48 小时内为自己写一个计划”,并完成了核心任务并想扩展它,但遇到了问题。我想做的是使eval
函数可用于运行时,但在将其存储到全局环境中时遇到问题。
运行时环境的类型:
type Env = IORef [(String, IORef LispVal)]
Haskelleval
实现的类型为:
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
经常发生在代码中,所以不清楚为什么它在这里不起作用。我将非常感谢对我的错误的启发。作为参考,我的代码几乎与作为参考的原始教程的最终代码完全一样。
谢谢