haskell - OCaml 中的有序变体类型和子类型

标签 haskell compare ocaml algebraic-data-types

我目前正在尝试在 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]

唉,ocaml 顶层返回
[Joker; Card(Spade, Ace); Card(Diamond, Num 2); Card(Diamond, Num 3)]

(这已经相当不错了!)

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

我读过这篇 article on polymorphic comparethis similar question但我不确定我是否要依赖 compare_val .

我真的必须编写自己的比较函数吗?如果你推荐我写一篇,你有没有关于它应该写的方式的提示,特别是减少案例的数量?

P.S.:我刚刚听说 deriving(Ord)在 Haskell... 可能足以让我迈出这一步...

最佳答案

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

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 分钟内轻松完成。

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

关于haskell - OCaml 中的有序变体类型和子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17173101/

相关文章:

haskell - 使用 randomR 生成奇怪的有偏差随机数

c++ - 在 C++ 中插入优先级队列时如何解决段错误

php - 比较变量 PHP

css - css样式表比较和缩减用什么工具

ocaml - ocaml 对象语法 `object(...)` 的含义是什么?

ocaml - 尝试平均变量时出现语法错误

haskell - 我的 Haskell 包可以依赖哪些版本的包?

haskell - 什么是 hs 文件?为什么使用 ".hsfiles"扩展名而不是常规的 ".hs"?

haskell - 在编译时通过文件内容初始化函数

ocaml - 如何让 ocamlopt 链接到 glibc 2.5?