这段简单的代码让我感到难过
所以这是有效的
> let l = [1; 2; 3; 4];;
val l : int list = [1; 2; 3; 4]
> List.reduce(fun accm i -> accm + i) l;;
val it : int = 10
但这并不是(即使逻辑完全相同)
> let l = [("a", 1); ("b", 2); ("c", 3); ("d", 4)];;
val l : (string * int) list = [("a", 1); ("b", 2); ("c", 3); ("d", 4)]
> List.reduce(fun accm tup -> accm + (snd tup)) l;;
List.reduce(fun accm tup -> accm + (snd tup)) l;;
>stdin(46,47): error FS0001: The type 'int' does not match the type 'string * int'
为什么我会收到此错误,因为代码很简单。遍历列表获取元组并将其与累加器的值一起传递给reduce函数。
函数内部的从元组中取第二个值并将其添加到累加器中。
我知道可能有很多其他方式可以获得我想要的东西......但我想知道为什么上面的代码不起作用?
答案 0 :(得分:3)
您需要提供初始值。如果没有初始值,则reduce
假定List
中的第一个值是初始值,即元组。因此你得到的错误。
答案 1 :(得分:2)
reduce
的参数应该彼此具有相同的类型和列表的元素(在这种情况下是元组类型),但是您要尝试将一个添加到另一半的后半部分。
答案 2 :(得分:2)
我认为你要做的是List.sumBy snd
。
reduce
假设累加器与列表项的类型相同,这不是问题中的reducer函数的假设。