我正在尝试编写一个能计算句子中单词的函数。
cwords :: String -> Int
cwords "" = 0
cwords (a:b:c)
|isAlpha a && (isAlpha b == False) = 1 + cwords (b:c)
|otherwise = cwords (b:c)
每当我输入一个句子时,我都会收到一条错误,上面写着“函数cwords中的非详尽模式”。空字符串工作正常。 (我对Haskell很新)
答案 0 :(得分:5)
问题是您定义了两个子句:
一个空列表
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
不是isAlpha
,那么我们不必在(b:c)
执行递归,但可以直接在c
执行递归;和otherwise
个案重写为处理包含至少一个元素的列表的子句。导致:
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