Search code examples
haskelliostdout

How to print IO String - "Couldn't match type ‘IO String’ with ‘[Char]’ Expected type: String Actual type: IO String"


I want this function to print a given IO String

day :: IO String -> IO ()
day p2 = do
  putStr "p2: "
  putStrLn p2

But the compiler says that it needs [Char], but from what I know it's basically the same as String, so my question is how do I print out IO String?

Also this is what the error that stack run outputs:

    • Couldn't match type ‘IO String’ with ‘[Char]’
      Expected type: String
        Actual type: IO String
    • In the first argument of ‘putStrLn’, namely ‘p2’
      In a stmt of a 'do' block: putStrLn p2
      In the expression: do putStrLn p2    • Couldn't match type ‘IO String’ with ‘[Char]’
      Expected type: String
        Actual type: IO String
    • In the first argument of ‘putStrLn’, namely ‘p2’
      In a stmt of a 'do' block: putStrLn p2
      In the expression: do putStrLn p2
   |
17 |   putStrLn p2
   |            ^^

I tried doing putStr ("p2: " ++ p2) and using print but with no success :(


Solution

  • The compiler's error message is actually very clear. The argument to putStrLn has to be a String (or [Char], the two types are synonyms of each other), but your p2 is not a String but an IO String.

    The same fundamental error occurs in both of the other things you say you have tried - they can't get round this issue.

    It's not totally clear what you want to do. I see two possibilities:

    • if you simply want to print out a string, then you don't want the input to be an IO String at all, but a simple String. If you simply change the type signature accordingly, this will compile with no problem.

    • perhaps you do indeed want to take an action of type IO String (such as getLine) as an input. In that case, you can use do notation (which you're already using anyway) to bind the output of the action, which is an actual String, to a variable and then call putStrLn with that:

      day :: IO String -> IO ()
      day p2 = do
         putStr "p2: "
         s <- p2
         putStrLn s