How can I use Seq.sum for any .Net value types?

I'm looking for a function that processes the seq of any numeric data type (int, float, double), does a little computation on it through a mapping, and then sums those computed values. The problem I am running into is that Seq.sum (or really just "(+)" in general) causes the type parameters to be integers or just give an error. There seems to be a way to make this work using type constraints, but I can't seem to get it.

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

      

This is similar to the syntax of the F # generics / function overload , but it didn't really explain how to make it work for all value types.

+3


source to share


1 answer


I got it like this. Read the answer related to Foggy Finder. Then you need a static member Zero

to work 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

      

+5


source







All Articles