Haskell - 定义交换函数:如何通过组合考虑实际参数,而不是排列

时间:2015-03-23 12:29:47

标签: haskell

我想定义一个函数,在不考虑它们的顺序的情况下考虑它的同类型参数。例如:

weirdCommutative :: Int -> Int -> Int
weirdCommutative 0 1 = 999
weirdCommutative x y = x + y

我希望这个功能实际上是可交换的。 一种选择是添加模式:

weirdCommutative 1 0 = 999

甚至更好:

weirdCommutative 1 0 = weirdCommutative 0 1

现在让我们看看一般情况:可能有两个以上的参数和/或两个值需要在没有顺序的情况下考虑 - 所以考虑所有可能的情况变得棘手。

有没有人知道在Haskell中定义交换函数的一种干净,自然的方法?

我想强调的是,我正在寻找的解决方案是通用的,不能假设任何关于类型(也不是它的解构类型集),除了可以使用==比较值(意味着类型是Eq类型类,但不一定在Ord类型类中。

2 个答案:

答案 0 :(得分:6)

实际上a package提供了monad和一些脚手架来定义和使用交换函数。另请参阅此blog post.

答案 1 :(得分:3)

在类似Int的情况下,您可以简单地对参数进行排序并将它们提供给只接受该规范有序形式的参数的(本地)部分函数:

weirdCommutative x y
  | x > y      = f y x
  | otherwise  = f x y
 where f 0 1 = 999
       f x' y' = x' + y'

现在,显然大多数类型都不在Ord类中 - 但是如果你通过模式匹配解构参数,你很可能至少定义一些偏序。它实际上不一定是>