I am working on an amazing one. Write yourself a scheme after 48 hours and complete the basic tasks and want to expand it, but ran into a problem. What I wanted to do was make the eval
function available at runtime, but you have a problem with storing it in the global environment.
The runtime has the type:
type Env = IORef [(String, IORef LispVal)]
The Haskell eval
implementation is of type:
eval :: Env -> LispVal -> IOThrowsError LispVal
The global environment is a mapping of the type:
primitiveBindings :: IO Env
since it contains functions that perform IO mixed with pure functions. My attempt was to set the eval
runtime to the eval
host, partially applied with a global environment like this:
baseFun :: [(String, [LispVal] -> IOThrowsError LispVal)] baseFun = [("eval", unaryOp (eval (liftIO $ readIORef primitiveBindings)))]
Where unaryOp
:
unaryOp :: (LispVal -> ThrowsError LispVal) -> [LispVal] -> ThrowsError LispVal unaryOp f [v] = fv
I would like to add elements to the global environment, but I get a compilation error:
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)'
It seems that this readIORef env
pattern is often found in code, so it is not clear why it does not work here. I am very grateful for the enlightenment in my mistakes. For reference, my code is almost exactly like the final code of the source tutorial as a reference.
thanks