Big Man
Big Man

Reputation: 5

Haskell take multiple input and outputs in a do block

I have been trying to take an input and output a list onto the console in the same do block and then for this function to be repeated through recursion, but I'm new to IO in haskell and can't see how to get it to work.

Also I'm not putting an break statement on the recursion because I can just break it by pressing control-c in the console when I'm done using it.

My code:

move2 m coords char = when (can_move m coords char) (print_maze (place_player m (move coords char)))

game_loop m coords = print_maze (place_player m coords)
    do 
        (char:chars) <- getLine
        maze2 <- move2 m coords (read char)
        putStrLn maze2
        putStrLn game_loop m coords

The line before the do block is meant to output a list, but not be repeated in the recursion.

Error Message:

Unexpected do block in function application:
        do (char : chars) <- getLine
           maze2 <- move2 m coords (read char)
           putStrLn maze2
           putStrLn game_loop m coords
    You could write it with parentheses
    Or perhaps you meant to enable BlockArguments?
    |
107 |     do
    |     ^^^^...

It says this is the only error but I'm sure theres other errors in the do block aswell. All of the other individual functions work fine by themselves.

I don't know how I would fix this so any information in IO would be appreciated, thank you.

Edit:

I got the do block to work now I just have a type error.

move2 m coords char = when (can_move m coords char) (print_maze (place_player m (move coords char)))

game_loop m coords = do
    print_maze (place_player m coords)
    let loop = do 
        (char:chars) <- getLine
        maze2 <- move2 m coords (char)
        putStrLn maze2
        if char /= 'c'
        then game_loop m coords
        else return ()
    loop

Error message:

Couldn't match type `()' with `[Char]'
      Expected type: String
        Actual type: ()
    * In the first argument of `putStrLn', namely `maze2'
      In a stmt of a 'do' block: putStrLn maze2
      In the expression:
        do (char : chars) <- getLine
           maze2 <- move2 m coords (char)
           putStrLn maze2
           if char /= 'c' then game_loop m coords else return ()
    |
111 |         putStrLn maze2
    |                  ^^^^^

Upvotes: 0

Views: 200

Answers (1)

chi
chi

Reputation: 116139

You can't put a line before a do block like that. If you want to do something before starting a loop, follow this scheme instead:

example :: IO ()
example = do
   putStrLn "this is the line before the loop, to be run once"
   let loop = do
          putStrLn "here we are inside the loop"
          if someCondition
          then loop      -- repeat the loop
          else return () -- stop the loop
   loop -- start the loop defined above

Upvotes: 2

Related Questions