我正在尝试编写一个函数来计算句子中的单词 .
cwords :: String -> Int cwords "" = 0 cwords (a:b:c) |isAlpha a && (isAlpha b == False) = 1 + cwords (b:c) |otherwise = cwords (b:c)
每当我输入一个句子时,我都会收到一条错误,上面写着“函数cwords中的非详尽模式” . 空字符串工作正常 . (我对Haskell很新)
问题是您定义了两个子句:
cwords "" = 0
cwords (a:b:c) = ...
所以Haskell说,如果字符串只包含一个字符,它就不知道该怎么做,因为没有子句指定在这种情况下要做什么 .
由于你计算单词,如果我们获得最后一个字符,我们应该把它算作一个单词(假设它是一个字母字符) . 所以代码应该是:
至:
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 ;
not (isAlpha b)
isAlpha b == False
如果我们知道 b 不是 isAlpha ,那么我们不必在 (b:c) 上执行递归,但可以直接在 c 上执行递归;和
b
isAlpha
(b:c)
c
我们可以将 otherwise case重写为处理包含至少一个元素的列表的子句 .
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
1 回答
问题是您定义了两个子句:
所以Haskell说,如果字符串只包含一个字符,它就不知道该怎么做,因为没有子句指定在这种情况下要做什么 .
由于你计算单词,如果我们获得最后一个字符,我们应该把它算作一个单词(假设它是一个字母字符) . 所以代码应该是:
至:
话虽这么说,我们仍然可以改进代码:
我们可以使用
not (isAlpha b)
而不是isAlpha b == False
;如果我们知道
b
不是isAlpha
,那么我们不必在(b:c)
上执行递归,但可以直接在c
上执行递归;和我们可以将
otherwise
case重写为处理包含至少一个元素的列表的子句 .导致: