的问题是,你定义两个条款:
一个与空列表
cwords "" = 0
和一个在列表中包含在至少两个元素:
cwords (a:b:c) = ...
所以Haskell说它不知道该怎么办,以防字符串只包含一个字符,因为没有子句指定在这种情况下要做什么。
既然你计算单词,如果我们获得最后一个字符,我们应该把它算作一个单词(因为它是一个字母字符)。因此,代码应为:
cwords :: String -> Int
cwords "" = 0
cwords (a:b:c)
|isAlpha a && (isAlpha b == False) = 1 + cwords (b:c)
|otherwise = cwords (b:c)
到:
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)
话虽这么说,我们仍然可以提高代码:
- 我们可以使用
not (isAlpha b)
代替isAlpha b == False
;
- 如果我们知道
b
不,那么我们就必须在(b:c)
执行递归在这里,但可以直接在c
执行递归;和
- 我们可以将
otherwise
大写字母重写为处理至少包含一个元素的列表的子句。
所得为:
如果该字符串有一个字符? –
谢谢!你是对的。我在想是isAlpha b == False覆盖那一个。 – batlord