Search code examples
haskellmonadsio-monad

Haskell: Couldn't match expected type 'IO b' with actual type bool


I get the following error:

Couldn't match expected type `IO b' with actual type `Bool'
In the expression:
  upCheck
    ["########", "#11xxx3#", "#xx2xx3", "#002xx3", ....] 2 [2, 3, 4]
In the expression:
  do { s <- readFile "projekt-board.txt";
       let content = lines s;
       printTable content;
       printHelp;
       .... }
In an equation for `gameFunc':
    gameFunc
      = do { s <- readFile "projekt-board.txt";
             let content = ...;
             printTable content;
             .... }

With the definition for gameFunc:

gameFunc = do
  s <- readFile "projekt-board.txt"
  let content = lines s
  printTable content
  printHelp
  upCheck ["########","#11xxx3#","#xx2xx3","#002xx3","#7x2x44#"] 2 [2,3,4] 

and function upCheck:

upCheck :: [[Char]] -> Int -> [Int] -> Bool
upCheck tableArr number posArr = do
  --posArr saadakse findBlock funktsiooniga
  let arv = findVIndex (findVertIndex tableArr number)
  let str = tableArr !! (posArr !! 0)
  if ((posArr !! 0) == 1)
  then False
  else if arv == (-1)
    then False
    else if isHorizontal str number
      then False
      else if (tableArr !! ((posArr !! 0)-1)) !! arv /= 'x'
        then False
        else True

So basically what is happening here is that upCheck is a function to check whether some conditions are matched and when I call it out the same way from ghci as i call it out from the function gameFunc, i will get a result True. However, if I call it out from the function gameFunc I get an error described above. Any ideas what went wrong?


Solution

  • The problem is that your function gameFunc uses a do expression which is syntactical sugar for a monad (in this case the IO monad). You can turn any non-monadic result into a monadic one by using the return function:

    return :: Monad m => a -> m a
    

    So you can rewrite your gameFunc to (see last line):

    gameFunc = do
      s <- readFile "projekt-board.txt"
      let content = lines s
      printTable content
      printHelp
      return $ upCheck ["########","#11xxx3#","#xx2xx3","#002xx3","#7x2x44#"] 2 [2,3,4]
    

    Now gameFunc has the type IO Bool. You can use gameFunc in other monadic environment like:

    main = do
        b <- gameFunc
        print b
    

    in order to print the result of gameFunc.