The problem is that you define two clauses:
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:
- we can use
not (isAlpha b) instead of isAlpha b == False;
- if we know
b is not isAlpha, then we do not have to perform recursion on (b:c) here, but can directly perform recursion on c; and
- we can rewrite the
otherwise 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