私は48時間で驚くべきWriteYourselfa Schemeに取り組んでおり、コアタスクを完了し、それを拡張したいと思っていましたが、問題が発生しました。私がやりたかったのは、eval
関数をランタイムで使用できるようにすることですが、それをグローバル環境に保存する際に問題があります。
ランタイム環境のタイプは次のとおりです。
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
コードで頻繁に発生するように見えるため、ここで機能しない理由は不明です。私の過ちについての啓蒙を大いに感謝します。参考までに、私のコードは、参照としての元のチュートリアルの最終的なコードとほぼ同じです。
ありがとうございました