I may have been away from F# for too long, but I would have expected this to compile:
module Calc
let foo values = List.sum values
Instead, I get a compilation error:
FS0071 Type constraint mismatch when applying the default type 'obj' for a type inference variable. The type 'obj' does not support the operator '+' Consider adding further type constraints
This also happens for List.average, so at first I thought it had something to do with generic constraints like requires member ( + ) and member get_Zero, but that can't be the whole story, since let foo values = List.max values compiles (List.max also has a generic constraint, albeit a simpler one - it only requires comparison).
What am I doing wrong?
This is a .NET 5.0 project. Compilation fails both in Visual Studio and with dotnet build.
List.sum has an SRTP type with a requirement that the element of the list has a (+) operator defined on it:
val sum:
list: list< ^T>
-> ^T (requires static member ( + ) and static member Zero )
When you try to call that without knowing the type of the list element, the compiler can't resolve the SRTP.
One option would be to mark foo itself inline:
let inline foo values = List.sum values
That way, foo itself will inherit the SRTP requirement:
val foo:
values: list< ^a>
-> ^a (requires static member ( + ) and static member Zero )
And you're just kicking the problem down the line - presumably to the point where you know the type of the element.
This doesn't work without an inline modifier, because SRTPs can't be compiled to IL.
Another option, if you can afford it, is to specify an element type, such that it has a (+) operator:
let foo (values: int list) = List.sum values
This way the compiler can resolve SRTP right there by observing that int does indeed have a (+) operator.
This works fine with List.max, because max doesn't have an SRTP constraint on it. It only has an 'T :> IComparison constraint, which are supported by the IL, so they don't have to be SRTP.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With