OCaml中的有序变量类型和子类型

问题描述 投票:7回答:2

[我目前正在尝试在OCaml中进行一些麻将手工处理,从一开始我就直接遇到困扰我的东西。

我将基于卡片提供示例,因为我不想将任何人与麻将术语混淆。

就像在此part on User-Defined Types from OCaml for the Skeptical中一样,我想使用变体类型来描述西服,卡片和所有物品。

type suit = Club | Diamond |  Heart | Spade
type value = Jack | Queen | King | Ace | Num of int
type card = Card of suit * value | Joker
type hand = card list

而且如果我可以编写一个智能的compare函数来理解有序变量类型,那将非常好。

理想情况下,我会这样写:

type suit = Club < Diamond <  Heart < Spade
type value = Num of int < Jack < Queen < King < Ace
type card = Card of suit * value < Joker
type hand = card list

所以当我这样做

List.sort Pervasives.compare [Card(Diamond, Num 3); Joker; Card(Spade, Ace); Card(Diamond, Num 2)]

它给了我

[Card(Diamond, Num 2); Card(Diamond, Num 3); Card(Spade, Ace); Joker]

A,ocaml顶级返回

[Joker; Card(Spade, Ace); Card(Diamond, Num 2); Card(Diamond, Num 3)]

(已经很好!)

基本上我想要一个compare函数,该函数可以从类型声明结构中获取提示。

我已经阅读过此article on polymorphic comparethis similar question,但不确定是否要依赖compare_val

我真的必须编写自己的比较函数吗?如果您建议我写一篇,那么您是否对编写方式有一些建议,特别是减少案例数?

P.S .:我刚刚在Haskell听说过deriving(Ord) ...可能足以让我跳起来...

haskell compare ocaml algebraic-data-types
2个回答
8
投票

是的,你必须。但是您可以跳过多态比较与您的需求匹配的地方。例如,您不需要写西服的比较。

Haskell的deriving(Ord)与多态比较相同:如果您可以在脑海中按顺序对构造函数进行排序,则可以派生比较函数。但是它功能更强大,因为您可以组合自动和自定义比较功能。 OCaml的多态比较无法做到这一点。例如,

type t = ...
let compare_t = .... (* custom comparison for t *)
type t2 = A of t | B of t | C of t (* I want to write a comparion for t2 now! *)

如果构造函数A,B和C的多态比较顺序符合您的需要,则您不能将其用于t2的比较,因为它无法调用t的自定义比较。因此,在这种情况下,如果我是您,我会手工编写compare_t2。对于您的卡片示例来说,只需3分钟即可轻松完成。

如果您的数据类型巨大,并且用手写下所有比较非常痛苦,则可以像使用deriving(Ord)一样,使用CamlP4和type_conv从类型定义中自动生成比较函数。但是,恐怕还没有提供类似于Ord之类的type_conv模块。就我个人而言,我从来没有感到需要它。对于P4学习者来说,这应该是一个不错的练习。


0
投票

我迟了7年,但是您可以使用ppx_deriving:]实现这一目标

type value = Num of int | Jack | Queen | King | Ace [@@deriving ord]
type suit = Club | Diamond | Heart | Spade [@@deriving ord]
type card = Card of suit * value | Joker [@@deriving ord]
type hand = card list

使用ocamlfind ocamlopt -o executable.out -linkpkg -package ppx_deriving.ord file.ml链接包。

© www.soinside.com 2019 - 2024. All rights reserved.