check whitespace in string in inductive step of function in haskell

Viewed 89

I am trying to count the length of string excluding whitespaces. I can't use length,filter and if-else. Only recursion. My current code is:

countLetters :: String -> Int
countLetters "" = 0
countLetters str = 1+ countLetters(tail str)

What i tried to do,

countLetters :: String -> Int
countLetters "" = 0
countLetters (" ",xs) = 0 + countLetters(xs)
countLetters str = 1+ countLetters(tail str)

But what i got instead is:

Couldn't match type `([Char], String)' with `[Char]'
  Expected type: String
    Actual type: ([Char], String)
In the pattern: (" ", xs)
  In an equation for `countLetters':
      countLetters (" ", xs) = 0 + countLetters (xs)

I also tried removing the extra inductive step and enumerating the condition,

fromEnum head str!=" "

So if head of the string is whitespace then the value would be 1 but != is not a valid operator. even == would yield,

   head str == " "
<interactive>:22:13: error:
    * Couldn't match expected type `Char' with actual type `[Char]'
    * In the second argument of `(==)', namely `" "'
      In the expression: head str == " "
      In an equation for `it': it = head str == " "

So Please help me find another method.

1 Answers

You made two mistakes here. First of all the "cons" of a list uses (:) as data constructor, so you work with (" ":xs), not (" ",xs).

Furthermore a String is a list of Chars, so that means that the elements are Chars, not Strings, therefore you should use ' ', not " ":

countLetters :: String -> Int
countLetters "" = 0
countLetters (' ':xs) = countLetters xs
countLetters str = 1 + countLetters (tail str)

Typically it is also better to work with pattern matching instead of working with head and tail, since tail raises an error for an empty list, and by using pattern matching, we know that the list is not empty:

countLetters :: String -> Int
countLetters "" = 0
countLetters (x:xs)
    | x == ' ' = countLetters xs
    | otherwise = 1 + countLetters xs
Related