F# - How do I extend a type with get_Zero so I can use an existing type generically?

守給你的承諾、 提交于 2019-12-01 17:36:20

List.sum uses static member constraints. Static member constraints don't look into extensions methods so that's not an option.

Wrapping the whole complex type is an option but it's overkill, if it is just a specific call you have many ways to compute the sum with a few more keystrokes, you can use a fold as shown on the other answer. Alternatively you can use List.reduce (+) if you are sure that the list will always have at least one element.

This might be possible to get fixed in a future version of F# but the problem is that static member constraints don't work with fields, unless they have a getter. However in the F# lib they can "emulate" those members for existing types, they do it normally with primitive types otherwise it wouldn't work with int, float, since they don't have that member either.

I'm not sure if the fact that Complex is defined in System.Numerics was the reason not to implement it this way, or may be they just forgot it. In any case you can open an issue or submit a pull request to get it fixed.

Finally another option if you still want to use it in a generic way is to redefine the sum function. For instance the sum function (here's the source) from the latest F#+ version will work fine (it had the same problem but was very easy to fix, actually it was a bug) with practically all numeric types, including Complex and most third party numeric types because it has a fallback mechanism which relies in some conversions when the type doesn't have a get_Zero member.

List.sum doesn't recognize a Zero defined as extension. It must be part of the type.

Use List.fold instead:

let sum = [c 1.0; c 2.0] |> List.fold (+) Complex.Zero

BTW System.Numerics.Complex actually has a static Zero, but it's a field, not a property.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!