Sequinex
Sequinex

Reputation: 671

Haskell: Expected type: [Char] Actual type: [[Char]]

I recently started learning Haskell and in my program I am getting the following error:

    Couldn't match type ‘[Char]’ with ‘Char’
Expected type: [Char]
  Actual type: [[Char]]
In the first argument of ‘head’, namely ‘input’
In the first argument of ‘magi’, namely ‘(head input)’

My code looks like this:

vocals = ["a", "e", "i", "o", "u","y"]
vocal o
  | elem o vocals == True = True --return true if the letter is a vowel
  | elem o vocals == False = False --else false

magi konsonant = [konsonant] ++ "o" ++ [konsonant]

rovarsprak input
  |length input == 0 = ""
  |length input > 0 && vocal (head input) == False = magi (head input) ++ rovarsprak (tail input)
  |length input > 0 && vocal (head input) == True = head input : rovarsprak (tail input)

As I understand, I am getting the error because of my input to the head function is [[char]] instead of [char], but I don't understand why the input to head is a [[char]]. Thanks!

Upvotes: 0

Views: 797

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476584

The problem is that vocal has type:

vocal :: String -> Bool

This is because vocals is a list of Strings, and thus elem will here check if a string is in the list of strings.

and therefore Haskell derives that since you call vocal (head input), input itself should be a list of Strings.

We can easily alter this into:

vocals = ['a', 'e', 'i', 'o', 'u', 'y']

Or shorter:

vocals = "aeiouy"

That being said, your code is quite chaotic. We can rewrite it into:

vocals :: [Char]
vocals = "aeiouy"

vocal :: Char -> Bool
vocal = flip elem vocals                   -- pointfree function

magi :: Char -> String
magi konsonant = konsonant : 'o' : [konsonant]

rovarsprak :: String -> String
rovarsprak "" = ""                         -- use patterns
rovarsprak (h:t)                           -- use patterns to unpack
    | vocal h = h : rovarsprak t           -- == True is not necessary
    | otherwise = magi h ++ rovarsprak t   -- use otherwise

The line vocal = flip elem vocals works as follows: flip takes as input a function f that takes two arguments x and y. It then turns it into a function that takes two arguments y and x (so the arguments are flipped).

What we want is to call elem o vocals. This is equivalent to flip elem vocals o. Now by using eta-reduction, we can omit the o (both in the head and the body of the clause).

Upvotes: 4

Related Questions