Add ArgMin / ArgMax pattern synonyms
import Data.Semigroup
pattern ArgMin :: a -> b -> ArgMin a b
pattern ArgMin a b = Min (Arg a b)
pattern ArgMax :: a -> b -> ArgMax a b
pattern ArgMax a b = Max (Arg a b)
Or even record pattern synonyms, à la this
pattern ArgMin :: a -> b -> ArgMin a b
pattern ArgMin {minArg, minValue} = Min (Arg minArg minValue)
pattern ArgMax :: a -> b -> ArgMax a b
pattern ArgMax {maxArg, maxValue} = Max (Arg maxArg maxValue)
and we can define
import Data.Semigroup.Foldable
argmin :: Ord k => Foldable1 f => (a -> k) -> (f a -> a)
argmin f = minValue . foldMap1 (\a -> ArgMin (f a) a)
argmax :: Ord k => Foldable1 f => (a -> k) -> (f a -> a)
argmax f = maxValue . foldMap1 (\a -> ArgMax (f a) a)