我刚刚想到,f#泛型似乎不接受常量值作为"模板参数"。
假设想要创建一个类型RangedInt
,它的行为像int,但保证只包含整数值的子范围。
一种可能的方法是区分联合,类似于:
type RangedInt = | Valid of int | Invalid
但是这也不起作用,因为没有"范围信息的特定类型存储"。2个RangedInt实例应该是不同的类型,如果范围也不同的话。
仍然是c++的一部分,它看起来类似于:
template<int low,int high>
class RangedInteger { ... };
现在出现的问题是双重的:
- 我错过了什么,f#泛型存在常量值吗?
- 如果我没有错过这一点,那么在f#中完成这样的
RangedInt<int,int>
的惯用方法是什么?
发现了Tomas Petricek关于自定义数字类型的博客,相当于我对那篇博客文章的问题是:如果他没有IntegerZ5
而是IntegerZn<int>
自定义类型家族怎么办?
您请求的语言特性称为依赖类型,而f#没有该特性。
这不是一个特别常见的语言特性,甚至Haskell(大多数其他函数式编程语言都"崇拜")也没有。
有有依赖类型的语言,但我认为它们都不是主流。我听到最多的可能是Idris。
我错过了什么,f#泛型的常数值存在吗?
虽然f#比其他。net语言有更强的类型推断,但它的核心是建立在。net之上的。
. net泛型只支持c++模板的一小部分功能。泛型类型的所有类型参数都必须是类型,也没有默认的类型参数。
如果我没有错过,在f#中实现这样一个RangedInt的惯用方法是什么?
这取决于细节。在运行时设置限制是一种可能——这是。net中常用的方法。另一个是度量单位(这似乎不太合适)。
如果他没有
IntegerZ5
而是IntegerZn<int>
自定义类型家族呢?
我看到两个原因:
- 这是一个例子,避免泛型可以让事情更简单,让人们专注于例子的要点。
- 我们还会使用什么其他底层类型?在当代系统上,较小的类型(
byte
,Int16
等)效率较低(除非运行时的空间是压倒性的关注);long
会增加大小而没有好处(它只会保存5个可能的值)。