Home > Blockchain >  Couldn´t match expected type error in haskell
Couldn´t match expected type error in haskell

Time:02-20

I´m trying to implement a function that saves the highest score of a player in a game through a txt file. This is the code:

import System.IO
import System.Directory

saveHighScore:: Int -> IO()
saveHighScore num = do
  let stringNum = ""    show num
  let file = "score.txt"
  writeFile file stringNum

readHighScore:: IO() -> Int
readHighScore = do 
  content <- openFile "score.txt" ReadMode
  score <- hGetContents content
  let highScore = read score :: Int
  return highScore

But the code is giving this error and I don´t know what to do:

localStorage.hs:17:9: error:
* Couldn't match expected type: IO () -> Int
              with actual type: IO Int
* In a stmt of a 'do' block:
    content <- openFile "score.txt" ReadMode
  In the expression:
    do content <- openFile "score.txt" ReadMode
       score <- hGetContents content
       let highScore = ...
       return highScore
  In an equation for `readHighScore':
      readHighScore
        = do content <- openFile "score.txt" ReadMode
             score <- hGetContents content
             let highScore = ...
             ....
 |
17|         content <- openFile "score.txt" ReadMode
 |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

CodePudding user response:

The error message is telling you exactly what's wrong. You claim your function has type IO () -> Int, but it's impossible for any interesting function to have this type. The only possible implementation is a constant function that ignores the IO () and produces the same result regardless of its input.

The right type is the one the compiler is suggesting, IO Int.

CodePudding user response:

In the other answer, amalloy gives the explanation.

To fix the issue, the easiest step is to remove the type declaration:

readHighScore = do 
  content <- openFile "score.txt" ReadMode
  score <- hGetContents content
  let highScore = read score :: Int
  return highScore

Then load the file in GHCi and query GHCi about the type:

> :t readHighScore
readHighScore :: IO Int

That's the type. You can add it back as a type declaration:

readHighScore :: IO Int
readHighScore = do 
  content <- openFile "score.txt" ReadMode
  score <- hGetContents content
  let highScore = read score :: Int
  return highScore

There are lots of tools and add-ons that can do this in your IDE of choice, but GHCi works everywhere, I should think.

  • Related