为什么我的类型总是比后面的类型大?

时间:2019-02-09 09:38:39

标签: types ocaml

我在ocaml中使用类型进行作业分配,并且一切正常,除了我的卡片值类型,尽管命名方式以整数命名,但总会导致整数卡片的得分高于面部卡片。

我认为您之后输入的任何类型名称都按升序顺序排列,以更高的价格显示?那么为什么Simple of int总是比其他类型大?

我知道是否将所有值都放入

type value = Two | Three... | King | Ace

可以使用,但是分配要求Simple of int用于数字卡。

type value = Simple of int | Jack | Queen | King | Ace

Simple 9 > Jack //should be false but is true
Queen > Jack    //should be true and is true

任何一个Simple of int都应该小于Jack而不是Queen等。但是似乎每个Simple of int都比Ace大。

2 个答案:

答案 0 :(得分:0)

简单构造函数具有有效负载,而其他构造函数则没有。 Ocaml参考手册谈到了结构排序函数,例如运算符(>),“这些函数与整数,字符,字符串,字节序列和浮点数的常规排序一致,并将它们扩展为所有类型的总排序。排序与(=)“

兼容

因此,出于这些功能的目的,具有相同变体类型的构造函数具有总顺序(这样,除其他事项外,对于相同的参数,运算符(=)和(>)永远都不会为真)必然是您将视为“通常”的顺序。

一种方法是编写一个函数,该函数在变量上匹配模式并根据您自己想要的顺序返回一个数值,然后可以将其与运算符(>)进行比较。

答案 1 :(得分:0)

通常最好定义自己的比较函数,而不要依赖于内置的多态比较(而不是依赖于值的内部存储器表示)。例如

 let (<) x y = match x, y with
 | Simple n, Simple m -> n < m
 | Simple _, _
 | Jack, ( Queen | King | Ace )
 | Queen, ( King | Ace )
 | King, Ace -> true
 | _ -> false

或者您可以投影为一对整数

 let num = function
 | Simple n -> 0, n
 | Jack -> 1, 0
 | Queen -> 1, 1
 | King -> 1, 2
 | Ace -> 1, 3

然后将<定义为

let (<) x y = num x < num y

为了不影响多态比较,将此自定义(<)运算符的定义放在子模块(例如Infix)中,然后将其与本地开放语法一起使用可能更为实用。 :Infix.( x < y )

回到最初的问题,多态比较函数认为带有参数的变量构造函数大于没有参数的构造函数。换句话说,如果您定义

   type t = A | B of int | C | D of int

构造函数的顺序为A < C < B < D。值得注意的是,此定义应用于列表时会产生通常的词典顺序。实际上,列表本质上被定义为

type 'a list = 
| [] 
| (::) of 'a * 'a list

然后,顺序[] < (::)意味着对于任何元素x和列表q[] < a :: q