rausch
rausch

Reputation: 3398

IO troubles in Haskell

As an exercise I am trying to implement a game in Haskell. What I don't seem to have grasped, yet, is how IO works. I read, that something like this would work in order to make the IO String that getLine returns usable in pure code:

main = do
  foo <- getLine
  do_something_with foo

The code I ended up with got slightly more complex and I don't understand why it wouldn't work. My code looks like this:

game_loop game = do
  show game
  coords <- getLine
  game_loop (add_move game (parse_coords coords))

main = game_loop new_game

The errors I get look like this:

src/main.hs:5:13:
    Couldn't match type ‘IO’ with ‘[]’
    Expected type: [String]
      Actual type: IO String
    In a stmt of a 'do' block: coords <- getLine
    In the expression:
      do { show game;
           coords <- getLine;
           game_loop (add_move game (parse_coords coords)) }

src/main.hs:8:1:
    Couldn't match expected type ‘IO t0’ with actual type ‘[b0]’
    In the expression: main
    When checking the type of the IO action ‘main’ }

Where line 5 is the one with the <- and 8 is the one with main =.

Upvotes: 1

Views: 97

Answers (1)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64750

When you use 'do' notation your statements should be of type Monad m => m a. Lets look at the types and what monad they imply...

game_loop game = do
  show game                  -- :: [Char] so this implies the list monad, []
  coords <- getLine          -- :: IO String so this implies the IO monad
  game_loop (add_move game (parse_coords coords)) -- :: m a

So you probably want the IO monad and instead of show you would use print:

gameLoop game =
  do print game
     gameLoop . addMove game . parseCoords =<< getLine

Upvotes: 4

Related Questions