Data.Semigroup 中 ArgMin 和 ArgMax 类型同义词的用途是什么?

ill*_*out 8 haskell monoids argmax semigroup type-synonyms

base哈斯克尔库具有以下类型同义词在Data.Semigroup

type ArgMin a b = Min (Arg a b)

type ArgMax a b = Max (Arg a b) 
Run Code Online (Sandbox Code Playgroud)

这是黑线鳕的链接:ArgMinArgMax

这两种类型的同义词的目的是什么?在哪里可以有效地使用它们?

解释 argmin 和 argmax 函数在数学中的作用以及它们与这些类型同义词的关系可能会有所帮助。


这里有一些额外的信息,因此您不必跳到 Hackage。

这是 的定义Arg

-- | 'Arg' isn't itself a 'Semigroup' in its own right, but it can be
-- placed inside 'Min' and 'Max' to compute an arg min or arg max.
data Arg a b = Arg a b
Run Code Online (Sandbox Code Playgroud)

它的文档字符串表明ArgMinandArgMax可以放在里面MinMax计算 arg min 或 arg max。

MinMax如下所示:

newtype Min a = Min { getMin :: a }
Run Code Online (Sandbox Code Playgroud)

这个Semigroup例子很有趣:

instance Ord a => Semigroup (Min a) where
  (<>) = coerce (min :: a -> a -> a)
Run Code Online (Sandbox Code Playgroud)

看起来它正在使用minas (<>)

我们可以看看Ord实例的样子Arg,因为它在这里是相关的:

instance Ord a => Ord (Arg a b) where
  Arg a _ `compare` Arg b _ = compare a b
  min x@(Arg a _) y@(Arg b _)
    | a <= b    = x
    | otherwise = y
  max x@(Arg a _) y@(Arg b _)
    | a >= b    = x
    | otherwise = y
Run Code Online (Sandbox Code Playgroud)

这似乎只对第一个类型参数运行比较Arg

Mar*_*ann 5

我想它是 Haskell 中存在的事物之一,因为存在理论概念。我不确定这些类型是否有很多实际用途,但它们确实说明了半群和幺半群的概念在编程方面的广泛性。

例如,想象一下,您需要选择两个名称中最长的一个,name1并且name2,它们的String值都相同。您可以为此使用Semigroup实例ArgMax

Prelude Data.Semigroup> Max (Arg (length name1) name1) <> Max (Arg (length name2) name2)
Max {getMax = Arg 5 "Alice"}
Run Code Online (Sandbox Code Playgroud)

在那之后,这只是"Alice"从容器中解开包装的问题。

正如 Willem Van Onsem 在评论中指出的那样,您可以根据项目的某些属性使用ArgMaxArgMin选择最大或最小项目,但仍保留原始项目。

  • 我之前在实际代码中使用过它。我们想要实现一个类似分配器的东西,可以很容易地将空间块添加回池中并从池中获取最大的空间块(但有更多关于我们想在比较中忽略的块的信息) 。我们使用了带有“ArgMax”的现有堆实现;完毕。另一种看待它的方式:它本质上是装饰-排序-取消装饰模式,但用于最小/最大而不是排序。 (6认同)