No F# generics with constant “template arguments”?

浪尽此生 提交于 2019-12-08 20:40:47

问题


It just occurred to me, that F# generics do not seem to accept constant values as "template parameters".

Suppose one wanted to create a type RangedInt such, that it behaves like an int but is guaranteed to only contain a sub-range of integer values.

A possible approach could be a discriminated union, similar to:

type RangedInt = | Valid of int | Invalid

But this is not working either, as there is no "type specific storage of the range information". And 2 RangedInt instances should be of different type, if the range differs, too.

Being still a bit C++ infested it would look similar to:

template<int low,int high>
class RangedInteger { ... };

Now the question, arising is two fold:

  1. Did I miss something and constant values for F# generics exist?
  2. If I did not miss that, what would be the idiomatic way to accomplish such a RangedInt<int,int> in F#?

Having found Tomas Petricek's blog about custom numeric types, the equivalent to my question for that blog article would be: What if he did not an IntegerZ5 but an IntegerZn<int> custom type family?


回答1:


The language feature you're requesting is called Dependent Types, and F# doesn't have that feature.

It's not a particularly common language feature, and even Haskell (which most other Functional programming languages 'look up to') doesn't really have it.

There are languages with Dependent Types out there, but none of them I would consider mainstream. Probably the one I hear about the most is Idris.




回答2:


Did I miss something and constant values for F# generics exist?

While F# has much strong type inference than other .NET languages, at its heart it is built on .NET.

And .NET generics only support a small subset of what is possible with C++ templates. All type arguments to generic types must be types, and there is no defaulting of type arguments either.

If I did not miss that, what would be the idiomatic way to accomplish such a RangedInt in F#?

It would depend on the details. Setting the limits at runtime is one possibility – this would be the usual approach in .NET. Another would be units of measure (this seems less likely to be a fit).

What if he did not an IntegerZ5 but an IntegerZn<int> custom type family?

I see two reasons:

  • It is an example, and avoiding generics keeps things simpler allowing focus on the point of the example.
  • What other underlying type would one use anyway? On contemporary systems smaller types (byte, Int16 etc.) are less efficient (unless space at runtime is the overwhelming concern); long would add size without benefit (it is only going to hold 5 possible values).


来源:https://stackoverflow.com/questions/32602760/no-f-generics-with-constant-template-arguments

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