user2568495
user2568495

Reputation:

Why is the recursive case not working?

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

Answers (2)

Chris Taylor
Chris Taylor

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

fjarri
fjarri

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 Strings 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

Related Questions