哈斯克尔错误:非

我试图写一个函数来计算句子中的单词。

cwords :: String -> Int
cwords "" = 0
cwords (a:b:c)
    |isAlpha a && (isAlpha b == False) = 1 + cwords (b:c) 
    |otherwise = cwords (b:c)

每当我输入一个句子时,我都会收到一个错误,说“功能词汇中的非穷举模式”。 一个空字符串正常工作。 (我对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)
    

    至:

    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
    
    链接地址: http://www.djcxy.com/p/43283.html

    上一篇: Haskell error: non

    下一篇: exhaustive patterns using if