有没有更好的方法在 F#/OCaml 中编写交换函数?

Is there a better way to write a commutative function in F#/OCaml?

有没有比列出所有可能情况更优雅或更好的方法来用 F#/OCaml 编写交换函数?

let commutative x y = 
    match x,y with
        a, _ -> val1
       |_, a -> val1
       |b, _ -> val2
       |_, b -> val2
       ...
       |_,z -> |valN

当我写这个问题时,我认为可以使函数递归并在找不到匹配项时交换参数。

let rec commutative x y = 
    match x,y with
     a,_ -> val1
    |b,_ -> val2
     ...
    |nox,noy -> commutative noy nox

但是如果我采用这种方法,我就不能在函数中有一个与所有匹配的默认情况,除非我添加另一个参数,该参数的值指示它是否是第二次调用该函数并且 return 默认值如果是这种情况,而不是使用交换的 args 调用函数。

还有其他想法吗? 该语言是否提供了一种结构来表达我定义的函数是可交换的?

(我回答 OCaml 只是因为我的 F# 非常生锈。)

OCaml 对定义交换函数没有特别的帮助。

如果您的参数类型具有合理的排序关系,您可以在必要时交换它们以使 x 更大(比如说)。几乎所有类型都可以在 OCaml 中进行比较,因此这应该非常普遍。 (不能比较的东西:函数类型,循环值。)

我不确定这是否有帮助,但它可能会减少您需要写出的案例数量:

let commutative x y =
    match (max x y, min x y) with
    | A, _ -> value
    . . .