模式匹配中的链接子句,如何添加缺失的绑定

Chaining clauses in a pattern match, how to add missing bindings

我定义了一个类型:

type quantity = Value of int | Direction of int * int | Vector of int * int * int

后来我有函数可以同时对后两种子类型的值进行操作:

match q with
| Direction(x, y)
| Vector(x, y, magnitude) ->

如果第一个模式匹配,是否有某种方法可以将幅度定义为 0?我知道我可以使用 let x, y, magnitude = match (...) 将类型转换为元组,或者将 Vector 和 Direction 合并为一个子类型,在适当的地方将 magnitude 设置为 0。 但我正在寻找简洁的东西。

我不确定我是否理解你的问题。如果第一个模式匹配,则数量属于方向子类型,因此没有向量。因此,根据您的要求,它可能是这样的,

match q with
| Direction (x,y)
| Vector (x,y,0) -> 

它将匹配方向或幅度为零的矢量。

或者,如果“将幅度定义为 0”是指创建一个幅度为零的矢量,方向应映射到该矢量,则可以按以下方式完成,

match q with
| Direction (x,y) -> Vector (x,y,0)

您不能将添加绑定绑定到模式 ( match q with Direction(x,y) and m = 0 -> 在幻想语法中)。然而,在这种情况下,定义一个幅度函数似乎很简单

let magnitude = function
  | Direction _ | Value _-> 0 
  | Vector (_,_,m) -> m

然后使用它:

match q with
| Direction(x, y)
| Vector(x, y, _) ->
  let magnitude = magnitude q in
  ...

另一方面,需要从 variant 生成魔法值的情况往往表明您的类型定义不符合基本概念。

比如,为什么一个方向的大小为0?为什么向量有幅度作为一个组成部分?如果向量变体的前两个参数实际上是一个方向,为什么在类型中不明显?