在撰写大学作业的过程中,我正在愉快地学习新的Haskell单子。耶!!!
我有一个类型检查良好的函数:
但当这个其他函数被调用时:
我有一个类型检查良好的函数:
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。
也许有一些巧妙的方法可以解开这个 state monad?也许可以重写“编译”,使其在运行过程中输入一些状态单子信息,但最终返回一个字符串(不包含任何单子)?
如果我漏掉了任何信息,请告诉我。
IO
单子的可怕的unsafePerformIO
,但你不应该使用它。 - Matthew Walton$
)。感谢提醒。对于许多单子,都有相应的函数,但并非所有单子都有。IO
就是其中没有这样函数的一个 [好吧,有一个名字以unsafe
开头的函数,它真的真的很不安全]。有runIdentity
、runReader
、runWriter
、runCont
等等。查看每个单子的文档,看看是否有这样的函数。 - Daniel Fischer