0

I'm a beginner in Haskell, and I'm stuck on an IO problem that I can't get to solve.

I'm working on a Snake game, and the only thing i've got to do left is taking user input to make the snake move. So here's my function

--Get char
input :: IO Char
input =
    hSetEcho stdin False
    >> hSetBuffering stdin NoBuffering
    >> getChar

myFunction :: IO Char -> Int -> Int
myfunction myChar oldValue
     | (myChar == 'q') = 1
     | (myChar == 'w') = 2
     | (myChar == 'e') = 3
     | (myChar == 'r') = 4
     | otherwise = oldValue

-- At the beginning of the game, function is called like this
let dir = myFunction input 1 --To give the snake an initial direction

-- The game works with a function Turn that takes an Int as parameter 
-- which is the previous direction. let's call it oldDir
let newDir = myFunction input oldDir
-- Then I call Turn again with newDir as parameter

The problem comes from the (myChar == char) part, and is "Couldn't match expected type ‘IO Char’ with actual type ‘Char’"

How to compare IO Char with Char?

Short answer: I can't. Could you please help me with the longer answer? This question was probably asked a number of times, but I'm still stuck on this problem.

Thank you in advance for your answer!

Cordially,

Zawarudio
  • 85
  • 1
  • 16

1 Answers1

3

You have to lift the comparison into the IO monad. For example:

myFunction :: Char -> Int -> IO Int
myFunction 'q' _ = return 1
myFunction 'w' _ = return 2
myFunction 'e' _ = return 3
myFunction 'r' _ = return 4
myFunction _ x = return x

-- Actual return type depends on what the function actually does
someOtherFunction :: Int -> IO ?
someOtherFunction oldDir = do
   dir <- input
   newDir <- myFunction dir oldDir
   ...

Another (probably better) option is to keep myFunction a pure function, and use fmap if you need to apply it to an IO Char.

-- Note the change in the argument order
myFunction :: Int -> Char -> Int
myFunction _ 'q' = 1
...
myFunction x _ = x

someOtherFunction oldDir :: Int -> IO ?
   newDir <- fmap (myFunction oldDir) input
   ...
chepner
  • 497,756
  • 71
  • 530
  • 681