Ord实例的Haskell maximumBy

时间:2017-06-29 18:58:10

标签: haskell max

我一直发现自己想要一个功能,我总是需要自己实现它,但我觉得必须有内置功能。<​​/ p>

基本上,我想要的是maximummaximumBy之间的中间位置。

maximum获取Ord值列表并返回最大值。这是O(n)。

maximum :: (Ord a) => [a] -> a

maximumBy获取非Ord值列表和一个为它们排序的排序函数,并使用该函数计算最大值。这是O(nlogn)(或者无论其复杂程度如何)。

maximumBy :: (a -> a -> Ordering) -> [a] -> a

我希望maximumBy获取类型a的值列表和返回Ord值的a值的函数,并计算最大值{{1}使用a值。这将是O(n),因为它只需跟踪最大值。这就是签名:

Ord

这是我粗略的实施:

maximumBy' :: (Ord b) => (a -> b) -> [a] -> a

是否内置了这样的功能,或者使用现有内置函数编写此功能的简单方法?

4 个答案:

答案 0 :(得分:5)

首先,你提出错误的说法:

  

maximumBy获取非Ord值列表和为它们提供排序的sort函数,并使用该函数计算最大值。这是 O(nlogn)

不需要进行排序来计算最大元素。排序关系必须是自反反对称传递,因此,到目前为止,人们可以简单地保持最大值,并使用自定义比较以检查新项目是否更大。

此外,您可以将maximumBy'函数构建为:

maximumBy' f = maximumBy (compare `on` f)

答案 1 :(得分:4)

我认为您正在寻找的内容可以使用Data.Ord.comparing

轻松表达

而不是使用maximumBy'功能:

maximumBy' head ["abc", "def", "geh"]

您可以使用comparing构建一个比较器并将其提供给通常的maximumBy

maximumBy (comparing head) ["abc", "def", "geh"]

正如Willem Van Onsem在另一个回答中所说的那样,关注maximumBy的费用是不正确的:它不会对列表进行排序。

答案 2 :(得分:4)

该函数被定义为the tip-lib package

maximumOn :: (Foldable f, Ord b) => (a -> b) -> f a -> b

一般的想法也是adopted in recent base, with

sortOn :: Ord b => (a -> b) -> [a] -> [a]

请注意,由于懒惰,您可以使用

maximumOn :: Ord b => (a -> b) -> [a] -> b
maximumOn f = head . sortOn f

并获得与手动实现相同的渐近性能。

答案 3 :(得分:1)

我不知道任何内置函数可以执行您想要的操作,但您可以真正简化maximumBy'的实现。

您可以使用on例如:

import Data.Function (on)

maximumBy' :: Ord b => (a -> b) -> [a] -> a
maximumBy' f = maximumBy (compare `on` f)

事实上,这个定义非常简单,您可以按原样使用它,而不必定义maximumBy'