我正在尝试在为 定义运算符重载的记录类型上使用 List.fold +
,但是在尝试将(+)
运算符用作传递给 fold 的 lambda 时出现类型不匹配错误。这是一个简化的片段,可以说明我的问题:
// a record type that also includes an overload for '+'
type Person =
{ Name : string; Age: int }
static member ( + ) (x: Person, y: Person) = x.Age + y.Age
过+
载工作得很好
> jen + kevin;;
val it : int = 87
但是说我有一个人名单:
> let people = [kevin;jen];;
我不能使用 List.fold 来总结所有年龄:
> List.fold (+) 0 people;;
List.fold (+) 0 people;;
----------------^^^^^^
error FS0001: Type constraint mismatch. The type
int
is not compatible with type
Person
The type 'int' is not compatible with the type 'Person'
我猜问题是 F# 无法识别+
以这种方式传递时的重载,因为 fold 隐式键入列表,int
因为我使用 '0' 作为累加器。我不确定是否有可能让我的自定义运算符重载正常工作,如果可能的话,我缺少什么来实现它。(我假设可以使这项工作成为可能,因为您可以+
在花车上使用)。
编辑
我知道问题是类型不匹配。正如 JaredPar 所写,我知道我可以编写一个 lambda 来获取两个人的记录并添加年龄。那不是我的意思。问题是,在我看来,应该有一种方法可以让+
我已经写过的运算符重载被 fold 确认为有效的重载。
另一个编辑
感谢大家的意见。越来越清楚的一件事是,不可能做我想做的事,但这没关系。我学到了一些东西!我所看到的是,运算符重载的分辨率使得它们不能在每个上下文中工作——所以fold
没有无缝的方法可以让+
作为 lambda 传递的工作就像用作中缀 ala 时那样工作jen + kevin
。为什么这不起作用是完全有道理的。人们建议解决这个问题的解决方案基本上是一次性处理特定问题的fold
——我真正追求的是如何获得正确的运算符重载以在每种情况下都被选中(即foldback
等)——我不想写一堆特殊情况的代码来处理列表。很明显,F# 的运算符重载解决方案有一些限制,使其工作到肤浅的水平,这很好。