我正在尝试获取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
答案 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)
直到需要
评估x
或xs
。我们想到
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
惰性模式匹配仍然可能失败,但是在这里我们推迟使用x
和xs
直到知道不会。
length binListToDec
尝试计算函数本身的长度,而不是计算其参数的长度。上面使用了length
的正确参数。而且,通常可接受的空列表之和为0,而不是1。