Reputation: 13
I'm trying to write a function that will count the words in a sentence.
cwords :: String -> Int
cwords "" = 0
cwords (a:b:c)
|isAlpha a && (isAlpha b == False) = 1 + cwords (b:c)
|otherwise = cwords (b:c)
I keep getting an error saying "non-exhaustive patterns in function cwords" whenever I enter a sentence. An empty string works fine. (I'm very new to Haskell)
Upvotes: 1
Views: 96
Reputation: 476614
The problem is that you define two clauses:
one with the empty list
cwords "" = 0
and one where the list contains at least two elements:
cwords (a:b:c) = ...
So the Haskell says that it does not know what to do in case the string contains exactly one character, since there is no clause that specifies what to do in that case.
Since you count words, in case we obtain the last character, we should count this as a word (given it is an alpha-character). So the code should read:
cwords :: String -> Int
cwords "" = 0
cwords (a:b:c)
|isAlpha a && (isAlpha b == False) = 1 + cwords (b:c)
|otherwise = cwords (b:c)
to:
cwords :: String -> Int
cwords "" = 0
cwords [_] | isAlpha a = 1
cwords (a:b:c)
|isAlpha a && (isAlpha b == False) = 1 + cwords (b:c)
| otherwise = cwords (b:c)
That being said, we can still improve the code:
not (isAlpha b)
instead of isAlpha b == False
;b
is not isAlpha
, then we do not have to perform recursion on (b:c)
here, but can directly perform recursion on c
; andotherwise
case as a clause that handles lists with at least one element.Resulting into:
cwords :: String -> Int
cwords "" = 0
cwords [a] | isAlpha a = 1
cwords (a:b:c) |isAlpha a && not (isAlpha b) = 1 + cwords c
cwords (_:b) = cwords b
Upvotes: 5