在Haskell中获取清单的总和

时间:2018-11-13 18:10:37

标签: list haskell

我正在尝试获取Haskell中列表的总和,但它给出了错误,请参见下面的代码。

binListToDec :: [Int] -> Int
binListToDec (x:xs) = if length binListToDec == 0 then 1
                      else x + binListToDec xs

出现以下错误

 * No instance for (Foldable ((->) [Int]))
        arising from a use of `length'
    * In the first argument of `(==)', namely `length binListToDec'
      In the expression: length binListToDec == 0
      In the expression:
        if length binListToDec == 0 then 1 else x + binListToDec xs
  |
2 | binListToDec (x:xs) = if length binListToDec == 0 then 1

1 个答案:

答案 0 :(得分:3)

在您可以用多种方式编写此代码时,有两种可能是

binListToDec xs = if length xs == 0 then 0  -- see below
                  else (head xs) + binListToDec (tail xs)

binListToDec [] = 0
binListToDec (x:xs) = x + binListToDec xs

您似乎正在尝试合并每个位。无法编写同时匹配以下内容的单个模式:1)一个空列表和2)一个非空列表,其中3)头部和尾部分别匹配。

  • xs匹配1)和2)。
  • all@(x:xs)匹配2)和3)
  • 1)和3)无法匹配,因为配对是荒谬的:空列表没有单独的头部和尾部。 [](x:xs)匹配两个不重叠的可能列表值集中的列表。

    更新:存在 lazy 模式匹配all@(~(x:xs))。代字号可防止尝试进行匹配(x:xs)直到需要 评估xxs。我们想到

    binListToDec all@(~(x:xs)) = if length all == 0 then 0 else x + binListToDec
    

    等同于

    binListToDec all = if length all == 0 
                       then 0
                       else let (x:xs) = all 
                            in x + binListToDec
    

    惰性模式匹配仍然可能失败,但是在这里我们推迟使用xxs直到知道不会。


length binListToDec尝试计算函数本身的长度,而不是计算其参数的长度。上面使用了length的正确参数。而且,通常可接受的空列表之和为0,而不是1。