Haskell错误:非穷举模式

Haskell错误:非穷举模式,haskell,Haskell,我正在尝试写一个函数来计算句子中的单词 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 :: 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 (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
    执行递归;及
  • 我们可以将
    案例重写为一个子句,该子句至少处理一个元素的列表
导致:

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

问题在于您定义了两个子句:

  • 有空名单的人

    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)
致:

尽管如此,我们仍然可以改进代码:

  • 我们可以使用
    not(isAlpha b)
    代替
    isAlpha b==False
  • 如果我们知道
    b
    不是
    isAlpha
    ,那么我们不必在这里对
    (b:c)
    执行递归,而是可以直接对
    c
    执行递归;及
  • 我们可以将
    案例重写为一个子句,该子句至少处理一个元素的列表
导致:

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

如果字符串只有一个字符呢?谢谢!你说得对。我在想isAlpha b==False覆盖了那个字符。如果字符串只有一个字符呢?谢谢!你说得对。我想isAlpha b==False涵盖了这一点。