Ocaml:使用布尔运算符进行模式匹配

its*_*ieb 1 ocaml boolean pattern-matching

我正在尝试编写一个函数"dom_rank r1 r2",它根据两张扑克牌的相对等级返回一个布尔值(等级是我定义的类型,它有值"Six","Seven","Eight"... ......"国王","王牌").如果r1是King而r2是Jack,则r1大于r2并且函数返回true,如果r1是Six而r2是Ten,则函数返回false.据我所知,我可以列出两种卡输入的所有可能性(我只处理六张牌,这有三种不同的可能性),但我正在尝试编写更简单的代码.该方法看起来像:

let dom_rank r1 r2 = match r1, r2 with
  | Ace, _ -> true
  | King, (Queen || Jack || Ten ........) -> true
Run Code Online (Sandbox Code Playgroud)

我在布尔表达式"(Queen || Jack || Ten ........)"的开头遇到语法错误.为什么我不能以这种方式列出r2的几种可能性?有没有办法在Ocaml中编写这个表达式?

Pat*_*atJ 5

"||" operator是一个布尔运算符,你必须用简单的"|"分隔模式,如下所示:

| King, (Queen | Jack | Ten | ... ) -> true
Run Code Online (Sandbox Code Playgroud)

但是,使用这种方法,你仍然会在很长一段时间内写下"六"这个词.一个好的方法是巧妙地使用通配符:

match r1, r2 with
| Ace, _ -> true
| _, Ace -> false (* at this point, neither card is an ace *)
| King, _ -> true
| _, King -> false
| Queen, _ -> true
| (* and so on *)
Run Code Online (Sandbox Code Playgroud)

这样,每个卡片级别只有两个模式,并且没有键入两次以上的卡片名称(并且可以复制粘贴非卡片名称)

一种不太安全但方便的方法是检查您的类型定义是否按正确的顺序排列:

type rank = Six | Seven | Eight | ... | Ace
let () = assert ( Six < Eight )
Run Code Online (Sandbox Code Playgroud)

根据这个定义,相对于标准比较运算符,卡应该处于良好的顺序(参见模块Pervasives).请务必进行一些测试,因为对该类型的任何修改都可能会破坏您的订单.