Reputation:
I'm writing a Haskell function using pattern matching that looks like this.
printLine :: [Int] -> [String]
printLine [] = error "Lege lijst levert niets op"
printLine [x] = "+" : replicate x "-"
printLine (x:xs) = ('+' : replicate x "-") : printLine xs
The base cases work, but GHC gives me an error on the recursive case that looks like this:
Couldn't match expected type `Char' with actual type `[Char]'
In the second argument of `replicate', namely `"-"'
In the second argument of `(:)', namely `replicate x "-"'
In the first argument of `(:)', namely `('+' : replicate x "-")'
What am I doing wrong? Please keep in mind that I'm a beginner at Haskell and functional programming in general. I hope someone can help me out.
Upvotes: 2
Views: 165
Reputation: 47392
In Haskell, a String
is just a list of Char
.
The notation '-'
is used for a single character. The notation "-"
is used for a string, which in this case is a list consisting of one Char
.
The following are equivalent - they are both a single-character string consisting of the character '-'
and no other characters.
"-" = ['-']
You also need to use ++
rather than :
to append strings. The :
operator is used to prepend a single character to the front of a string.
Upvotes: 4
Reputation: 9726
Two mistakes here. First, note the difference between single and double quotes:
'+' :: Char
"+" :: String
You want to write "+"
instead of '+'
in the last line, because you want to attach a String
to a list of String
s returned by replicate
.
Second, the outer :
in the last line tries to connect [String]
and [String]
(return type of printLine
), but its type is a -> [a] -> [a]
, so it expects just a String
as its first argument. You want to use (++)
here, which concatenates two lists. This error gives you the quoted error message.
The corrected code is
printLine :: [Int] -> [String]
printLine [] = error "Lege lijst levert niets op"
printLine [x] = "+" : replicate x "-"
printLine (x:xs) = ("+" : replicate x "-") ++ printLine xs
Upvotes: 5