Haskell如何通过函数检查相等性

7
在Haskell中,我可以使用下面的代码:
sortBy (comparing snd) 

按元组中第二个值排序,有相应的函数吗?我已经想出了这个方法,但也许标准库中有更好的解决方案。

是否有测试等价性的等效函数?我已经想出了下面的代码,但是标准库中可能有更好的方法。

equalsBy :: Eq b => (a -> b) -> a -> a -> Bool
equalsBy f x y = f x == f y

最终目标是按第二个值对一组成对进行分组。通过这样做,我可以进行以下操作:
groupBy (equalsBy snd) pairs

替代

groupBy (\x y -> (snd x) == (snd y)) pairs

不太确定您的意思,您是在问一个稳定排序吗? - eazar001
1个回答

17

您正在寻找一个稍微高级一点的函数,称为on

> import Data.Function
> :t on
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c

那么我该怎么使用呢?就像这样!

> :t ( (==) `on` snd )
( (==) `on` snd ) :: Eq b => (a, b) -> (a, b) -> Bool

这意味着我们想要:

> groupBy ( (==) `on` snd) [ (1,3), (23,9), (42,9), (1,3), (48, 3), (18,18)]
[[(1,3)],[(23,9),(42,9)],[(1,3),(48,3)],[(18,18)]]

太棒了!

编辑:

我想指出比较on的关系。它只是on的一种专门用法!

> :t comparing
comparing      :: Ord a => (b -> a) -> b -> b -> Ordering
> :t (compare `on`)
(compare `on`) :: Ord b => (a -> b) -> a -> a -> Ordering

(注意类型变量已交换,但您可以看到类型是相同的)


另外,(compare \on`)on compare是相同的。虽然听起来不太好,但也许可以更明确地表达on`的参数顺序。 - David Young

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接