首页 > 解决方案 > 如何处理Haskell中递归函数中的侧IO操作?

问题描述

我是 Haskell 的新手。我想知道为什么这段代码:

main :: IO ()
main = run theWorld presentationIO

run dom showDom = do
       event <- readCommand
       dom' <- updateDomain dom event 
       showDom dom'
       run dom' showDom

..不起作用以及如何解决它。错误是:

simpleExampleTextGameV.0.2.hs:96:16: error:
    • Couldn't match expected type ‘IO World’ with actual type ‘World’
    • In a stmt of a 'do' block: dom' <- updateDomain dom event
      In the expression:
        do event <- readCommand
           dom' <- updateDomain dom event
           showDom dom'
           run dom' showDom
      In an equation for ‘run’:
          run dom showDom
            = do event <- readCommand
                 dom' <- updateDomain dom event
                 showDom dom'
                 ....
   |
96 |        dom' <- updateDomain dom event 
   |                ^^^^^^^^^^^^^^^^^^^^^^

为了重现它,您可以启动其余代码: https ://github.com/agutie58/landOfLispInHaskell/blob/main/simpleExampleTextGameV.0.2.hs

提前致谢!

标签: haskelliomonads

解决方案


第66 行updateDomain定义的函数返回。World

但是第96 行的“左箭头”需要箭头右侧的一元值,在当前单子中,在您的情况下是IO.

所以这意味着updateDomain应该 return IO World,而不仅仅是,如果你想在块World中的左箭头的右侧使用它。do

然而,正确的解决方案不是updateDomain返回IO World,而是放下左箭头。相反,使用let绑定dom'

run dom showDom = do
  event <- readCommand
  let dom' = updateDomain dom event 
  showDom dom'
  run dom' showDom

推荐阅读