putStrLn, type Char does not match [Char]
I have an haskell problem. putStrLn is supposed to take a [Char], or a String, and even though it seems like I give that to mr Compiler, he still complains.
*** Expression : putStrLn line
*** Term : line
*** Type : Char
*** Does not match : [Char]
The code that it refers to is this:
getV::[[(Char,Float)]] -> IO ()
getV [] = putStrLn ""
getV (x:xs) = do line <- getS x
putStrLn line <-- Complaining line
getV xs
getS::[(Char,Flo开发者_StackOverflow社区at)] -> String
getS [] = ""
getS ((c,f):str) = do a <- "(L" ++ [c] ++")" ++ getS str
return a
I did strip it a little bit, but it should be exactly the same behaviour. getS do return a String and that string is the argument for putStrLn. So what is the problem? :/
Since your getS
returns a String
, not an IO String
, there's no need to "extract" the pure value with <-
.
Just use
do
let line = getS x
putStrLn line
getV xs
Also, there's a mapM
function which you can
getV xs = mapM (putStrLn.getS) xs
and your getS
is using monads unnecessarily.
getS [] = ""
getS ((c,_):str) = "(L" ++ [c] ++ ")" ++ getS str
Of course, it's possible to write it using built-in functions only.
getS ps = concatMap (\(c,_) -> "(L" ++ [c] ++ ")") ps
The reason your code doesn't fail on the line <- getS x
line, and line
becomes a Char
is because List is also a monad. For instance, we can write the Cartesian product as
cartesian :: [a] -> [b] -> [(a,b)]
cartesian xs ys = do
x <- xs -- # Now x is of type 'a', representing any element in xs
y <- ys -- # Now y is of type 'b', representing any element in ys
return (x, y) -- # Return the tuple composed of any elements in xs and ys.
In fact, list comprehension is based on this monadic property of list.
cartesian xs ys = [(x, y) | x <- xs, y <- ys]
精彩评论