有maximumWith之类的东西吗? [英] Is there such a thing as maximumWith?

查看:56
本文介绍了有maximumWith之类的东西吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具体地说,我正在搜索函数'maximumWith',

Specifically I'm searching for a function 'maximumWith',

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

以下行为:

maximumWith length [[1, 2], [0, 1, 3]] == [0, 1, 3]
maximumWith null [[(+), (*)], []] == []
maximumWith (const True) x == head x

我的用例是选择列表中最长的单词.
为此,我想要类似于 maximumWith length 的东西.

My use case is picking the longest word in a list.
For this I'd like something akin to maximumWith length.

我以为存在这样的事情,因为 sortWith 等存在.

I'd thought such a thing existed, since sortWith etc. exist.

推荐答案

让我一起收集注释中的所有注释...

Let me collect all the notes in the comments together...

让我们看一下 sort .该系列有4个功能:

Let's look at sort. There are 4 functions in the family:

  • sortBy 是实际的实现.
  • sort = sortBy比较使用 Ord 重载.
  • sortWith = sortBy.比较是您所需的 maximumWith 的类似物.但是,此功能有问题.元素的排名是通过将给定的映射函数应用于元素来进行的.但是,排名不会被记录下来,因此,如果一个元素需要多次比较,排名将被重新计算.如果排名功能非常便宜,则只能无罪地使用.此类功能包括选择器(例如 fst )和 newtype 构造函数.YMMV在简单的算术和数据构造函数上.在这种低效率,定义的简单性及其在 GHC.Exts 中的位置之间,很容易推断出它的使用频率不高.
  • sortOn 通过在排名功能下将每个元素用其图像装饰成对,按等级排序,然后删除它们,从而解决了效率低下的问题.
  • sortBy is the actual implementation.
  • sort = sortBy compare uses Ord overloading.
  • sortWith = sortBy . comparing is the analogue of your desired maximumWith. However, this function has an issue. The ranking of an element is given by applying the given mapping function to it. However, the ranking is not memoized, so if an element needs to compared multiple times, the ranking will be recomputed. You can only use it guilt-free if the ranking function is very cheap. Such functions include selectors (e.g. fst), and newtype constructors. YMMV on simple arithmetic and data constructors. Between this inefficiency, the simplicity of the definition, and its location in GHC.Exts, it's easy to deduce that it's not used that often.
  • sortOn fixes the inefficiency by decorating each element with its image under the ranking function in a pair, sorting by the ranks, and then erasing them.

前两个在 maximum 中具有类似物: maximumBy maximum . sortWith 没有类比;您最好每次都写出 maximumBy(比较_).即使这样会更有效,也没有 maximumOn .定义 maximumOn 的最简单方法可能就是复制 sortOn :

The first two have analogues in maximum: maximumBy and maximum. sortWith has no analogy; you may as well write out maximumBy (comparing _) every time. There is also no maximumOn, even though such a thing would be more efficient. The easiest way to define a maximumOn is probably just to copy sortOn:

maximumOn :: (Functor f, Foldable f, Ord r) => (a -> r) -> f a -> a
maximumOn rank = snd . maximumBy (comparing fst) . fmap annotate
  where annotate e = let r = rank e in r `seq` (r, e)

maximumBy 中有一些有趣的代码,无法在列表上进行适当的优化.它也可以使用

There's a bit of interesting code in maximumBy that keeps this from optimizing properly on lists. It also works to use

maximumOn :: (Foldable f, Ord r) => (a -> r) -> f a -> a
maximumOn rank = snd . fromJust . foldl' max' Nothing
    where max' Nothing x = let r = rank x in r `seq` Just (r, x)
          max' old@(Just (ro, xo)) xn = let rn = rank xn
                                         in case ro `compare` rn of
                                                 LT -> Just (rn, xo)
                                                 _ -> old

这些实用指示可能有用:

These pragmas may be useful:

{-# SPECIALIZE maximumOn :: Ord r => (a -> r) -> [a] -> a #-}
{-# SPECIALIZE maximumOn :: (a -> Int) -> [a] -> a #-}

这篇关于有maximumWith之类的东西吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆