您编写的类型签名描述了三个 Ints 的列表:[Int, Int, Int]
. 但是,列表类型的长度不确定,并且您编写的数量函数似乎期望 Ints 的 3 元组,可以写为[(Int, Int, Int)]
; 无论如何,这可以从定义中得出。因此将第一个代码块加载到 ghci 中会产生:
test.hs:1:11:
Illegal type: '[Int, Int, Int]
一旦我提供更长的输入列表,就会出现第二个错误:
*Main> amount [(1,2,3),(4,5,6)]
*** Exception: test.hs:(2,1)-(5,13): Non-exhaustive patterns in function amount
这里的问题是两种模式都不匹配:您的列表模式具有一个或零个条目,但没有更多。看到这[(a, b, c)]
是一个重复的表达式,我们直接替换它怎么样?
amount [] = 0
amount xs = sum( map getBalance xs)
where getBalance :: (Int,Int,Int) -> Int
getBalance (d, e, f) = f
现在任何长度的 list 都将被传递给map
,这很好,因为它旨在处理任意长度。事实上,所以sum
我们甚至不需要为空列表添加特殊情况。
如果您想为长于一个的列表添加模式,传统的形式是x:xs
将其分解为 headx
和 tail xs
。该模式与空列表不匹配,因为它无法拆分。
您的原始代码的问题还在于它只为一个元组列表定义了一个版本。我们可以使用列表推导或映射来处理:
amount1 abcs = sum [c | (a,b,c) <- abcs]
amount2 = sum . map (\(a,b,c) -> c)
所有这些变体都做同样的事情,即使 amount2 甚至没有提到参数。