Reputation: 17
I was playing around with making custom list displays. The concept is really simple but I keep getting an IO() error. My code is:
displayList :: [Int] -> IO()
displayList [] = putStrLn ""
displayList (firstUnit:theRest) = putStrLn (show firstUnit ++ "\n" ++
displayList theRest)
The error code I am getting is:
• Couldn't match expected type ‘[Char]’ with actual type ‘IO ()’
• In the second argument of ‘(++)’, namely ‘(displayList theRest)’
In the first argument of ‘putStrLn’, namely
‘((show firstUnit) ++ (displayList theRest))’
In the expression:
putStrLn ((show firstUnit) ++ (displayList theRest))
The specific part of the line that is getting the error is the displayList theRest
not the putStrLn ((show firstUnit) ++
part.
I think I understand what is happening which is that when displayList theRest
is called in the line with the error it has the potential eventually after a few recursive calls to return an IO() type from the line displayList [] = putStrLn ""
which is not supported as input in the putStrLn
function. Would anyone know a way to solve this?
Upvotes: 0
Views: 215
Reputation: 2210
The problem with your code is fairly obvious: as the compiler tells you, you're trying to concatenate a string (((show firstUnit) ++
) with an IO()
(the return type of your function)
The solution can take two paths: either you want a function that returns the whole string, and then prints it all in one, or just print it step by step recursively. What I mean is:
displayList :: [Int] -> IO()
displayList = putStrLn . helper
where
helper :: [Int] -> String
helper [] = ""
helper (n:ns) = show n ++ "\n" ++ helper ns
This approach works fine, but I believe it's not tidy nor clear.
displayList' :: [Int] -> IO()
displayList' [] = putStrLn ""
displayList' (n:ns) = putStrLn (show n) >> displayList' ns
I think you can see how this version is easier to read. Also note that print :: Show a => a -> IO()
works exactly as putStrLn . show
Upvotes: 3