我正在寻找一个函数来处理任何数值类型的数据(int,float,double)的seq,通过映射对它进行一些计算,然后对这些计算值进行求和.我遇到的问题是Seq.sum(或者通常只是'(+)')会导致类型参数为整数,或者只是给出一个平坦的错误.似乎应该有一种方法通过使用类型约束来使这项工作,但我似乎无法得到它.
type ValueWithComputation<'v> = {Value: seq<'v>; Computation: 'v -> 'v}
let calculateAndCombine (x: ValueWithComputation<'v>) =
x.Value
|> Seq.map x.Computation
|> Seq.sum // sometimes gives error: "Could not resolve the ambiguity inherent in the use of operator '(+)'
let x = {Value= {1..10}; Computation= (fun x->x*2)}
let y = {Value= {(1.0)..(10.0)}; Computation= (fun x->x*x)}
let totalX = calculateAndCombine x //this causes the code force 'v to be int
let totalY = calculateAndCombine y //gives an error since this isn't an int
Run Code Online (Sandbox Code Playgroud)
这看起来类似于F#泛型/函数重载语法,但它并没有真正解释如何让它适用于所有值类型.
我让它像这样工作.阅读Foggy Finder链接的答案.然后,你需要额外的静态成员Zero的sum工作.
type ValueWithComputation< ^T when ^T: (static member (+): ^T * ^T -> ^T) and ^T: (static member Zero: ^T)> =
{ Value: seq< ^T>
Computation: ^T -> ^T }
let inline calculateAndCombine x =
x.Value
|> Seq.map x.Computation
|> Seq.sum
let x = {Value= {1..10}; Computation= (fun x->x*2)}
let y = {Value= {(1.0)..(10.0)}; Computation= (fun x->x*x)}
let totalX = calculateAndCombine x
let totalY = calculateAndCombine y
Run Code Online (Sandbox Code Playgroud)