0

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!

1 Answer 1

8

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
Sign up to request clarification or add additional context in comments.

6 Comments

Or dom' <- updateDomain dom <$> readCommand.
Thank you for all your comments Fyodor and also chepner, you are absolute all right, it works perfectly after that. But I do no fully understand the solution. It means that if a certain function like run that returns IO b (in this case run :: World -> (World -> IO a) -> IO b ), it means that all actions inside should be IO something ? I assume that event <- readCommand executes this action, whereas let is different (binding function).
And let say that in another case, i was forced that a function foo had to return something as IO World. How can I force it !? something like: foo world = (putStr "") world !? It is little strange no!?
In pure functions the chain of types it is clear, but when it comes IO actions it turns little confusing to me (and more if they are in "do" statement).
I cannot answer more questions in the comments. If you have more questions, please post them as separate questions.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.