Types ocaml中的类型级别整数

Types ocaml中的类型级别整数,types,ocaml,gadt,Types,Ocaml,Gadt,有谁能给我一些建议/建议,让我在OCaml(3.12)中创建类型级整数,支持对它们进行加法和减法运算 例如,如果我有如下表示的数字: type zero type 'a succ type pos1 = zero succ type pos2 = zero succ succ ... val add: pos2 -> pos1 -> pos3 我需要一种方法在如下类型上定义函数: type zero type 'a succ type pos1 = zero succ type

有谁能给我一些建议/建议,让我在OCaml(3.12)中创建类型级整数,支持对它们进行加法和减法运算

例如,如果我有如下表示的数字:

type zero
type 'a succ
type pos1 = zero succ
type pos2 =  zero succ succ
...
val add: pos2 -> pos1 -> pos3
我需要一种方法在如下类型上定义函数:

type zero
type 'a succ
type pos1 = zero succ
type pos2 =  zero succ succ
...
val add: pos2 -> pos1 -> pos3
小背景: 我正在尝试为物理维度上的操作移植一些haskell代码,我需要能够定义维度类型上的操作(7个类型级别整数的记录,表示7个基本SI单位的指数)。 我需要这样做,以避免动态绑定(使用对象时),并使编译器能够静态地计算和检查所有此类表达式


我目前的理解是,我应该制作一个GADT来实现作为类型构造函数的操作,但我仍然在努力实现这个想法,任何提示都将不胜感激。

您的示例让我认为您正在尝试做prolog风格的逻辑数,类似于

type fancyInt = Zero | Succ of fancyInt ;;
然后加上

let rec add a b = match a with Zero -> b | Succ c -> add c (Succ b);;

您的背景故事暗示了另一种解决方案,即创建一个表示距离的类。在内部存储该值,但您需要提供一个接口,允许您获取并设置当时所需的单位距离。或者,如果您希望继续使用函数方法,只需为您的单元创建类型,然后使用与Ocaml本身处理此类事情相同的函数,即米/公里

您也许可以使用奥列格的许多令人惊叹的结构之一:

Jane Street还建议使用一流的模块


免责声明:我非常欣赏这种来自远方的编程。

您可能还对Sam Lindley在2008年ML研讨会上发表的文章感兴趣。

他想要您提供的类型和函数,但在类型级别上。也就是说,类型成为一个类型族(集合),而您的值零和Succ成为类型。函数add变成了一个类型级函数,在OCaml中,它是一个参数化类型,我猜(?)。哈斯克尔一直在做这种事。我还没有在OCaml中看到它,这表明它可能不那么容易。谢谢stonemetal,但正如Jeffrey所说,我需要在类型级别上实现这一点,以便编译器可以在编译时执行这些操作,并使用类型检查器检查约束。这个想法是为了避免可能失败的运行时检查,这取决于执行时的情况(即捕获语义上非法的操作,如将时间添加到长度(不支持相对性,只是简单的旧牛顿物理),而将长度除以时间应该是合法的,并且会导致新类型的速度)。对不起,我的高阶编程能力不是很好。我可能会回到OO,构建代表您需要的各种类型的类。谢谢,我听到了您所说的,但在haskell中,所有类型类和其他类型的类都非常容易接合:)以及您发布的这些链接,我一直在查看它们,试图了解它们的本质,但从未成功地使这些模块适应我的需要。我不理解它们实现的类型平等约束,为什么它们如此重要,以及如何准确地使用它们来实现“更高级”的函数?我想我会再读几遍…我只是看了这些幻灯片;这个想法非常简单和酷。然而,在我看来,它只处理类型级别的添加。我看不到一种方法可以让减法在保持简单性的同时工作。如果你在跟踪国际单位制,我想你需要减法(和负整数)。@Jeffrey我很抱歉我的想法来得这么慢,但你知道OCaml有一个“GADT”分支,对吧?(显然,根据该页面,我们将使用3.13)是的,我听说“本地”GADT将在3.13中加入OCaml,这将是一个非常有趣的时代。我认为OP(Etion)可能希望在当前版本中使用一些东西,但GADT分支可能是可以接受的。量纲分析似乎是GADT的一个很好的测试用例。(我个人很想看到一些GADT代码示例,它不是一种小型语言的解释器。)您好,这很好,谢谢Pascal!我还没有完全算出负数,但由于范围将非常有限,目前的想法是将0移到4以支持[-3..3])。我在尝试ocamlgadt分支时犹豫不决,因为它需要在qnx上编译,并且一切都需要尽可能稳定。另外,我没有找到任何3.13的发布日期计划,所以我现在坚持使用3.12。再次感谢,我终于测试了这个版本,它运行得非常好。至于负数,诀窍是对“差分类型对”的第一个元素(例如-1is(zs*z))应用后继元素。在写了否定函数(交换,实际上)之后,正常的加法处理否定的效果很好。