gpt4 book ai didi

haskell - 解开 Haskell State Monad

转载 作者:行者123 更新时间:2023-12-02 06:26:35 26 4
gpt4 key购买 nike

在为大学撰写作业的过程中,我一直享受着学习新的 Haskell monad 的乐趣。耶!!!

我有一个可以很好地进行类型检查的函数:

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 一个字符串。

也许有一些巧妙的方法来打开这个状态单子(monad)?也许可以重写“compile”,以便它在运行时接受某些状态单子(monad)信息,但随后只返回一个字符串(不包含在任何单子(monad)中)?

如果我遗漏了任何信息,请告诉我。

最佳答案

compile progState VarsState monad 中的一个操作,因此您不能在 IO-do-block 中使用它。在 do block 中,所有行必须使用相同的 monad,在本例中是 IO

您需要“运行”compile 操作来获取结果,其中之一

runState :: State s a -> s -> (a,s)
evalState :: State s a -> s -> a
execState :: State s a -> s -> s

看你是否需要

  • 结果和最终状态
  • 唯一结果
  • 仅最终状态

就您而言,您只需要结果,因此 evalState 就是这样。

为此,您需要提供一个初始状态,它可能看起来像

maybe_compile_prog (OK prog) modulename = do
let s1 = evalState (compile prog) initialState
writeFile (modulename ++ ".m") ((header modulename) ++ s1)

但是对于所有传递的OK prog,为compile操作提供的初始状态将是相同的。如果这不正确,您也可以将初始状态作为参数传递。

关于haskell - 解开 Haskell State Monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16668320/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com