没有具有常量"template arguments"的 F# 泛型?



我刚刚想到,f#泛型似乎不接受常量值作为"模板参数"。

假设想要创建一个类型RangedInt,它的行为像int,但保证只包含整数值的子范围。

一种可能的方法是区分联合,类似于:

type RangedInt = | Valid of int | Invalid

但是这也不起作用,因为没有"范围信息的特定类型存储"。2个RangedInt实例应该是不同的类型,如果范围也不同的话。

仍然是c++的一部分,它看起来类似于:

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

现在出现的问题是双重的:

  1. 我错过了什么,f#泛型存在常量值吗?
  2. 如果我没有错过这一点,那么在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个可能的值)。

最新更新