在为大学写作业的过程中,我一直在享受学习新的 Haskell monads 的乐趣。耶!!!
我有一个可以很好地进行类型检查的函数:
compile :: Prog -> State VarsState String
compile prog@(Prog functions) = do
s1 <- sequence (map (translate_func 0) [get_function prog name | name <- [func_name func | func <- functions]])
return $ trace ("here's the program: \n" ++ show prog) $ concat $ s1
但是当这个其他功能:
maybe_compile_prog ::
MaybeOK Prog -> String -> IO ()
maybe_compile_prog (Error msg) _ = do
putStrLn ("error: " ++ msg)
maybe_compile_prog (OK prog) modulename = do
s1 <- compile prog
writeFile (modulename ++ ".m") ((header modulename) ++ s1)
试图打电话给它,它在线路上爆炸
s1 <- compile prog
说它无法将预期类型“IO t0”与实际类型“State VarsState String”匹配。
我认为这是因为 Maybe_compile_prog 返回类型 IO () 所以它只希望解开 IO 信息?VarsState 是我与 State monad/ 一起使用的自定义数据类型
但是,如果这是问题并且我认为是,我不知道如何将这个简单的字符串传输到maybe_compile_prog。真的,这就是我想做的——给maybe_compile_prog一个字符串。
也许有一些巧妙的方法来解开这个状态单子?也许可以重写“编译”,以便在运行时接收一些状态单子信息,然后只返回一个字符串(不包含在任何单子中)?
如果我遗漏任何信息,请告诉我。