简体   繁体   中英

how to deal with side IO operations in recursive functions in Haskell?

I am a complete newbie in Haskell. I am wondering why this pice of code:

main :: IO ()
main = run theWorld presentationIO

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

.. does not work and how to solve it. The error is :

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 
   |                ^^^^^^^^^^^^^^^^^^^^^^

In order to reproduce it, you could launch the rest of code: https://github.com/agutie58/landOfLispInHaskell/blob/main/simpleExampleTextGameV.0.2.hs

Thanks in advance!

The function updateDomain , as defined on line 66 , returns World .

But the "left arrow" on line 96 requires a monadic value on the right of the arrow, in the current monad, which in your case is IO .

So this means that updateDomain should return IO World , not just World , if you want to use it on the right side of the left arrow in a do block.

The right solution, however, is not to make updateDomain return IO World , but rather to drop the left arrow. Instead, use let to bind dom' :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM