{-# LANGUAGE RankNTypes #-}
module Fresnel.Fold1
( -- * Relevant folds
  Fold1
, IsFold1
  -- * Construction
, folded1
, unfolded1
, fold1ing
, foldMap1ing
, backwards
, iterated
, repeated
  -- * Elimination
, foldMap1Of
, foldMap1ByOf
, foldrMap1Of
, foldlMap1Of
, fold1Of
, fold1ByOf
, sequence1Of_
, traverse1Of_
, for1Of_
, toList1Of
, concatOf
, concatMapOf
, firstOf
, lastOf
, minimumOf
, minimumByOf
, maximumOf
, maximumByOf
  -- * Union semigroup
, Union(..)
) where

import Control.Applicative.Backwards
import Data.Functor (void)
import Data.Functor.Apply
import Data.List.NonEmpty (NonEmpty)
import Data.Profunctor
import Data.Profunctor.Unsafe ((#.), (.#))
import Data.Semigroup (First(..), Last(..))
import Data.Semigroup.Foldable
import Fresnel.Bifunctor.Contravariant
import Fresnel.Fold1.Internal (IsFold1)
import Fresnel.Functor.Ap1
import Fresnel.Functor.Traversed1
import Fresnel.Optic (Optic')
import Fresnel.Semigroup.Cons1 as Cons1
import Fresnel.Semigroup.Fork1 as Fork1
import Fresnel.Semigroup.Snoc1 as Snoc1
import Fresnel.Traversal1 hiding (backwards)

-- Relevant folds

type Fold1 s a = forall p . IsFold1 p => Optic' p s a


-- Construction

folded1 :: Foldable1 t => Fold1 (t a) a
folded1 :: forall (t :: * -> *) a. Foldable1 t => Fold1 (t a) a
folded1 = (forall m. Semigroup m => (a -> m) -> t a -> m) -> Fold1 (t a) a
forall a s.
(forall m. Semigroup m => (a -> m) -> s -> m) -> Fold1 s a
foldMap1ing (a -> m) -> t a -> m
forall m. Semigroup m => (a -> m) -> t a -> m
forall m a. Semigroup m => (a -> m) -> t a -> m
forall (t :: * -> *) m a.
(Foldable1 t, Semigroup m) =>
(a -> m) -> t a -> m
foldMap1

unfolded1 :: (s -> (a, Maybe s)) -> Fold1 s a
unfolded1 :: forall s a. (s -> (a, Maybe s)) -> Fold1 s a
unfolded1 s -> (a, Maybe s)
coalg = p s a -> p s s
forall (p :: * -> * -> *) a b c.
(Profunctor p, Bicontravariant p) =>
p a b -> p a c
rphantom (p s a -> p s s) -> (p a a -> p s a) -> p a a -> p s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (f :: * -> *). Apply f => (a -> f a) -> s -> f a)
-> Traversal1 s a a a
forall a b s t.
(forall (f :: * -> *). Apply f => (a -> f b) -> s -> f t)
-> Traversal1 s t a b
traversal1 (a -> f a) -> s -> f a
forall (f :: * -> *). Apply f => (a -> f a) -> s -> f a
forall {f :: * -> *} {a}. Apply f => (a -> f a) -> s -> f a
loop
  where
  loop :: (a -> f a) -> s -> f a
loop a -> f a
f s
s = let (a
a, Maybe s
s') = s -> (a, Maybe s)
coalg s
s in f a -> (s -> f a) -> Maybe s -> f a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (a -> f a
f a
a) ((a -> f a
f a
a f a -> f a -> f a
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Apply f => f a -> f b -> f b
.>) (f a -> f a) -> (s -> f a) -> s -> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> f a) -> s -> f a
loop a -> f a
f) Maybe s
s'

fold1ing :: Foldable1 t => (s -> t a) -> Fold1 s a
fold1ing :: forall (t :: * -> *) s a. Foldable1 t => (s -> t a) -> Fold1 s a
fold1ing s -> t a
f = (s -> t a) -> (s -> ()) -> p (t a) () -> p s s
forall a' a b' b. (a' -> a) -> (b' -> b) -> p a b -> p a' b'
forall (p :: * -> * -> *) a' a b' b.
Bicontravariant p =>
(a' -> a) -> (b' -> b) -> p a b -> p a' b'
contrabimap s -> t a
f (() -> s -> ()
forall a b. a -> b -> a
const ()) (p (t a) () -> p s s) -> (p a a -> p (t a) ()) -> p a a -> p s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (f :: * -> *). Apply f => (a -> f a) -> t a -> f ())
-> Traversal1 (t a) () a a
forall a b s t.
(forall (f :: * -> *). Apply f => (a -> f b) -> s -> f t)
-> Traversal1 s t a b
traversal1 (a -> f a) -> t a -> f ()
forall (f :: * -> *). Apply f => (a -> f a) -> t a -> f ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable1 t, Apply f) =>
(a -> f b) -> t a -> f ()
traverse1_

-- | Make a 'Fold1' by lifting a 'foldMap1'-like function.
--
-- @
-- 'foldMap1ing' 'foldMap1' = 'folded1'
-- 'foldMap1Of' . 'foldMap1ing' = 'id'
-- @
foldMap1ing :: (forall m . Semigroup m => (a -> m) -> (s -> m)) -> Fold1 s a
foldMap1ing :: forall a s.
(forall m. Semigroup m => (a -> m) -> s -> m) -> Fold1 s a
foldMap1ing forall m. Semigroup m => (a -> m) -> s -> m
fm = p s () -> p s s
forall (p :: * -> * -> *) a b c.
(Profunctor p, Bicontravariant p) =>
p a b -> p a c
rphantom (p s () -> p s s) -> (p a a -> p s ()) -> p a a -> p s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (f :: * -> *). Apply f => (a -> f a) -> s -> f ())
-> Traversal1 s () a a
forall a b s t.
(forall (f :: * -> *). Apply f => (a -> f b) -> s -> f t)
-> Traversal1 s t a b
traversal1 (\ a -> f a
f -> Ap1 f () -> f ()
forall (f :: * -> *) a. Ap1 f a -> f a
getAp1 (Ap1 f () -> f ()) -> (s -> Ap1 f ()) -> s -> f ()
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> (a -> b) -> a -> c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. (a -> Ap1 f ()) -> s -> Ap1 f ()
forall m. Semigroup m => (a -> m) -> s -> m
fm (f () -> Ap1 f ()
forall (f :: * -> *) a. f a -> Ap1 f a
Ap1 (f () -> Ap1 f ()) -> (a -> f ()) -> a -> Ap1 f ()
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> (a -> b) -> a -> c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. f a -> f ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (f a -> f ()) -> (a -> f a) -> a -> f ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f a
f))

-- | Reverse the order in which a (finite) 'Fold1' is traversed.
--
-- @
-- 'backwards' . 'backwards' = 'id'
-- @
backwards :: Fold1 s a -> Fold1 s a
backwards :: forall s a. Fold1 s a -> Fold1 s a
backwards Fold1 s a
o = p s () -> p s s
forall (p :: * -> * -> *) a b c.
(Profunctor p, Bicontravariant p) =>
p a b -> p a c
rphantom (p s () -> p s s) -> (p a a -> p s ()) -> p a a -> p s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (f :: * -> *). Apply f => (a -> f a) -> s -> f ())
-> Traversal1 s () a a
forall a b s t.
(forall (f :: * -> *). Apply f => (a -> f b) -> s -> f t)
-> Traversal1 s t a b
traversal1 (\ a -> f a
f -> Backwards f () -> f ()
forall {k} (f :: k -> *) (a :: k). Backwards f a -> f a
forwards (Backwards f () -> f ()) -> (s -> Backwards f ()) -> s -> f ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fold1 s a -> (a -> Backwards f a) -> s -> Backwards f ()
forall (f :: * -> *) s a r.
Apply f =>
Fold1 s a -> (a -> f r) -> s -> f ()
traverse1Of_ Optic' p s a
Fold1 s a
o (f a -> Backwards f a
forall {k} (f :: k -> *) (a :: k). f a -> Backwards f a
Backwards (f a -> Backwards f a) -> (a -> f a) -> a -> Backwards f a
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> (a -> b) -> a -> c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. a -> f a
f))

iterated :: (a -> a) -> Fold1 a a
iterated :: forall a. (a -> a) -> Fold1 a a
iterated a -> a
f = p a Any -> p a a
forall (p :: * -> * -> *) a b c.
(Profunctor p, Bicontravariant p) =>
p a b -> p a c
rphantom (p a Any -> p a a) -> (p a a -> p a Any) -> p a a -> p a a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (f :: * -> *). Apply f => (a -> f a) -> a -> f Any)
-> Traversal1 a Any a a
forall a b s t.
(forall (f :: * -> *). Apply f => (a -> f b) -> s -> f t)
-> Traversal1 s t a b
traversal1 (\ a -> f a
g -> let loop :: a -> f b
loop a
a = a -> f a
g a
a f a -> f b -> f b
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Apply f => f a -> f b -> f b
.> a -> f b
loop (a -> a
f a
a) in a -> f Any
forall {b}. a -> f b
loop)

-- | An infinite fold repeatedly producing its input.
--
-- @
-- 'Fresnel.Fold.toListOf' 'repeated' a = 'repeat' a
-- @
repeated :: Fold1 a a
repeated :: forall a (p :: * -> * -> *). IsFold1 p => Optic' p a a
repeated = p a Any -> p a a
forall (p :: * -> * -> *) a b c.
(Profunctor p, Bicontravariant p) =>
p a b -> p a c
rphantom (p a Any -> p a a) -> (p a a -> p a Any) -> p a a -> p a a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (f :: * -> *). Apply f => (a -> f a) -> a -> f Any)
-> Traversal1 a Any a a
forall a b s t.
(forall (f :: * -> *). Apply f => (a -> f b) -> s -> f t)
-> Traversal1 s t a b
traversal1 (\ a -> f a
f a
a -> let loop :: f b
loop = a -> f a
f a
a f a -> f b -> f b
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Apply f => f a -> f b -> f b
.> f b
loop in f Any
forall {b}. f b
loop)


-- Elimination

foldMap1Of :: Semigroup m => Fold1 s a -> ((a -> m) -> (s -> m))
foldMap1Of :: forall m s a. Semigroup m => Fold1 s a -> (a -> m) -> s -> m
foldMap1Of Fold1 s a
o = Forget m s s -> s -> m
forall {k} r a (b :: k). Forget r a b -> a -> r
runForget (Forget m s s -> s -> m)
-> (Forget m a a -> Forget m s s) -> Forget m a a -> s -> m
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> (a -> b) -> a -> c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. Forget m a a -> Forget m s s
Fold1 s a
o (Forget m a a -> s -> m)
-> ((a -> m) -> Forget m a a) -> (a -> m) -> s -> m
forall a b c (q :: * -> * -> *).
Coercible b a =>
(b -> c) -> q a b -> a -> c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible b a) =>
p b c -> q a b -> p a c
.# (a -> m) -> Forget m a a
forall {k} r a (b :: k). (a -> r) -> Forget r a b
Forget

foldMap1ByOf :: Fold1 s a -> ((r -> r -> r) -> (a -> r) -> (s -> r))
foldMap1ByOf :: forall s a r. Fold1 s a -> (r -> r -> r) -> (a -> r) -> s -> r
foldMap1ByOf Fold1 s a
o r -> r -> r
fork a -> r
leaf s
s = Fork1 a -> forall r. (r -> r -> r) -> (a -> r) -> r
forall a. Fork1 a -> forall r. (r -> r -> r) -> (a -> r) -> r
runFork1 (Forget (Fork1 a) s s -> s -> Fork1 a
forall {k} r a (b :: k). Forget r a b -> a -> r
runForget (Optic' (Forget (Fork1 a)) s a
Fold1 s a
o ((a -> Fork1 a) -> Forget (Fork1 a) a a
forall {k} r a (b :: k). (a -> r) -> Forget r a b
Forget a -> Fork1 a
forall a. a -> Fork1 a
Fork1.singleton)) s
s) r -> r -> r
fork a -> r
leaf

foldrMap1Of :: Fold1 s a -> ((a -> r) -> (a -> r -> r) -> (s -> r))
foldrMap1Of :: forall s a r. Fold1 s a -> (a -> r) -> (a -> r -> r) -> s -> r
foldrMap1Of Fold1 s a
o a -> r
last a -> r -> r
cons s
s = Cons1 a -> forall r. (a -> r) -> (a -> r -> r) -> r
forall a. Cons1 a -> forall r. (a -> r) -> (a -> r -> r) -> r
runCons1 (Forget (Cons1 a) s s -> s -> Cons1 a
forall {k} r a (b :: k). Forget r a b -> a -> r
runForget (Optic' (Forget (Cons1 a)) s a
Fold1 s a
o ((a -> Cons1 a) -> Forget (Cons1 a) a a
forall {k} r a (b :: k). (a -> r) -> Forget r a b
Forget a -> Cons1 a
forall a. a -> Cons1 a
Cons1.singleton)) s
s) a -> r
last a -> r -> r
cons

foldlMap1Of :: Fold1 s a -> ((a -> r) -> (r -> a -> r) -> (s -> r))
foldlMap1Of :: forall s a r. Fold1 s a -> (a -> r) -> (r -> a -> r) -> s -> r
foldlMap1Of Fold1 s a
o a -> r
first r -> a -> r
snoc s
s = Snoc1 a -> forall r. (a -> r) -> (r -> a -> r) -> r
forall a. Snoc1 a -> forall r. (a -> r) -> (r -> a -> r) -> r
runSnoc1 (Forget (Snoc1 a) s s -> s -> Snoc1 a
forall {k} r a (b :: k). Forget r a b -> a -> r
runForget (Optic' (Forget (Snoc1 a)) s a
Fold1 s a
o ((a -> Snoc1 a) -> Forget (Snoc1 a) a a
forall {k} r a (b :: k). (a -> r) -> Forget r a b
Forget a -> Snoc1 a
forall a. a -> Snoc1 a
Snoc1.singleton)) s
s) a -> r
first r -> a -> r
snoc

fold1Of :: Semigroup a => Fold1 s a -> (s -> a)
fold1Of :: forall a s. Semigroup a => Fold1 s a -> s -> a
fold1Of Fold1 s a
o = Fold1 s a -> (a -> a) -> s -> a
forall m s a. Semigroup m => Fold1 s a -> (a -> m) -> s -> m
foldMap1Of Optic' p s a
Fold1 s a
o a -> a
forall a. a -> a
id

fold1ByOf :: Fold1 s a -> ((a -> a -> a) -> (s -> a))
fold1ByOf :: forall s a. Fold1 s a -> (a -> a -> a) -> s -> a
fold1ByOf Fold1 s a
o a -> a -> a
fork s
s = Fork1 a -> forall r. (r -> r -> r) -> (a -> r) -> r
forall a. Fork1 a -> forall r. (r -> r -> r) -> (a -> r) -> r
runFork1 (Forget (Fork1 a) s s -> s -> Fork1 a
forall {k} r a (b :: k). Forget r a b -> a -> r
runForget (Optic' (Forget (Fork1 a)) s a
Fold1 s a
o ((a -> Fork1 a) -> Forget (Fork1 a) a a
forall {k} r a (b :: k). (a -> r) -> Forget r a b
Forget a -> Fork1 a
forall a. a -> Fork1 a
Fork1.singleton)) s
s) a -> a -> a
fork a -> a
forall a. a -> a
id

sequence1Of_ :: Apply f => Fold1 s (f a) -> (s -> f ())
sequence1Of_ :: forall (f :: * -> *) s a. Apply f => Fold1 s (f a) -> s -> f ()
sequence1Of_ Fold1 s (f a)
o = Traversed1 f a -> f ()
forall (f :: * -> *) a. Functor f => Traversed1 f a -> f ()
runTraversed1 (Traversed1 f a -> f ()) -> (s -> Traversed1 f a) -> s -> f ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fold1 s (f a) -> (f a -> Traversed1 f a) -> s -> Traversed1 f a
forall m s a. Semigroup m => Fold1 s a -> (a -> m) -> s -> m
foldMap1Of Optic' p s (f a)
Fold1 s (f a)
o f a -> Traversed1 f a
forall (f :: * -> *) a. f a -> Traversed1 f a
Traversed1

traverse1Of_ :: Apply f => Fold1 s a -> ((a -> f r) -> (s -> f ()))
traverse1Of_ :: forall (f :: * -> *) s a r.
Apply f =>
Fold1 s a -> (a -> f r) -> s -> f ()
traverse1Of_ Fold1 s a
o a -> f r
f = Traversed1 f r -> f ()
forall (f :: * -> *) a. Functor f => Traversed1 f a -> f ()
runTraversed1 (Traversed1 f r -> f ()) -> (s -> Traversed1 f r) -> s -> f ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fold1 s a -> (a -> Traversed1 f r) -> s -> Traversed1 f r
forall m s a. Semigroup m => Fold1 s a -> (a -> m) -> s -> m
foldMap1Of Optic' p s a
Fold1 s a
o (f r -> Traversed1 f r
forall (f :: * -> *) a. f a -> Traversed1 f a
Traversed1 (f r -> Traversed1 f r) -> (a -> f r) -> a -> Traversed1 f r
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> (a -> b) -> a -> c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. a -> f r
f)

for1Of_ :: Apply f => Fold1 s a -> (s -> (a -> f r) -> f ())
for1Of_ :: forall (f :: * -> *) s a r.
Apply f =>
Fold1 s a -> s -> (a -> f r) -> f ()
for1Of_ Fold1 s a
o = ((a -> f r) -> s -> f ()) -> s -> (a -> f r) -> f ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Fold1 s a -> (a -> f r) -> s -> f ()
forall (f :: * -> *) s a r.
Apply f =>
Fold1 s a -> (a -> f r) -> s -> f ()
traverse1Of_ Optic' p s a
Fold1 s a
o)

toList1Of :: Fold1 s a -> (s -> NonEmpty a)
toList1Of :: forall s a. Fold1 s a -> s -> NonEmpty a
toList1Of Fold1 s a
o = Fold1 s a -> (a -> NonEmpty a) -> s -> NonEmpty a
forall m s a. Semigroup m => Fold1 s a -> (a -> m) -> s -> m
foldMap1Of Optic' p s a
Fold1 s a
o a -> NonEmpty a
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

concatOf :: Fold1 s (NonEmpty a) -> (s -> NonEmpty a)
concatOf :: forall s a. Fold1 s (NonEmpty a) -> s -> NonEmpty a
concatOf = Fold1 s (NonEmpty a) -> s -> NonEmpty a
forall a s. Semigroup a => Fold1 s a -> s -> a
fold1Of

concatMapOf :: Fold1 s a -> ((a -> NonEmpty r) -> (s -> NonEmpty r))
concatMapOf :: forall s a r. Fold1 s a -> (a -> NonEmpty r) -> s -> NonEmpty r
concatMapOf = Fold1 s a -> (a -> NonEmpty r) -> s -> NonEmpty r
forall m s a. Semigroup m => Fold1 s a -> (a -> m) -> s -> m
foldMap1Of

firstOf :: Fold1 s a -> (s -> a)
firstOf :: forall s a. Fold1 s a -> s -> a
firstOf Fold1 s a
o = First a -> a
forall a. First a -> a
getFirst (First a -> a) -> (s -> First a) -> s -> a
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> (a -> b) -> a -> c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. Fold1 s a -> (a -> First a) -> s -> First a
forall m s a. Semigroup m => Fold1 s a -> (a -> m) -> s -> m
foldMap1Of Optic' p s a
Fold1 s a
o a -> First a
forall a. a -> First a
First

lastOf :: Fold1 s a -> (s -> a)
lastOf :: forall s a. Fold1 s a -> s -> a
lastOf Fold1 s a
o = Last a -> a
forall a. Last a -> a
getLast (Last a -> a) -> (s -> Last a) -> s -> a
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> (a -> b) -> a -> c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. Fold1 s a -> (a -> Last a) -> s -> Last a
forall m s a. Semigroup m => Fold1 s a -> (a -> m) -> s -> m
foldMap1Of Optic' p s a
Fold1 s a
o a -> Last a
forall a. a -> Last a
Last

minimumOf :: Ord a => Fold1 s a -> (s -> a)
minimumOf :: forall a s. Ord a => Fold1 s a -> s -> a
minimumOf Fold1 s a
o = Fold1 s a -> (a -> a -> Ordering) -> s -> a
forall s a. Fold1 s a -> (a -> a -> Ordering) -> s -> a
minimumByOf Optic' p s a
Fold1 s a
o a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare

minimumByOf :: Fold1 s a -> (a -> a -> Ordering) -> (s -> a)
minimumByOf :: forall s a. Fold1 s a -> (a -> a -> Ordering) -> s -> a
minimumByOf Fold1 s a
o a -> a -> Ordering
cmp = Fold1 s a -> (a -> a) -> (a -> a -> a) -> s -> a
forall s a r. Fold1 s a -> (a -> r) -> (r -> a -> r) -> s -> r
foldlMap1Of Optic' p s a
Fold1 s a
o a -> a
forall a. a -> a
id (\ a
a a
b -> case a -> a -> Ordering
cmp a
a a
b of
  Ordering
GT -> a
b
  Ordering
_  -> a
a)

maximumOf :: Ord a => Fold1 s a -> (s -> a)
maximumOf :: forall a s. Ord a => Fold1 s a -> s -> a
maximumOf Fold1 s a
o = Fold1 s a -> (a -> a -> Ordering) -> s -> a
forall s a. Fold1 s a -> (a -> a -> Ordering) -> s -> a
maximumByOf Optic' p s a
Fold1 s a
o a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare

maximumByOf :: Fold1 s a -> (a -> a -> Ordering) -> (s -> a)
maximumByOf :: forall s a. Fold1 s a -> (a -> a -> Ordering) -> s -> a
maximumByOf Fold1 s a
o a -> a -> Ordering
cmp = Fold1 s a -> (a -> a) -> (a -> a -> a) -> s -> a
forall s a r. Fold1 s a -> (a -> r) -> (r -> a -> r) -> s -> r
foldlMap1Of Optic' p s a
Fold1 s a
o a -> a
forall a. a -> a
id (\ a
a a
b -> case a -> a -> Ordering
cmp a
a a
b of
  Ordering
LT -> a
b
  Ordering
_  -> a
a)


-- Union semigroup

newtype Union s a = Union { forall s a. Union s a -> Fold1 s a
getUnion1 :: Fold1 s a }

instance Semigroup (Union s a) where
    Union Fold1 s a
a1 <> :: Union s a -> Union s a -> Union s a
<> Union Fold1 s a
a2 = Fold1 s a -> Union s a
forall s a. Fold1 s a -> Union s a
Union (p s () -> p s s
forall (p :: * -> * -> *) a b c.
(Profunctor p, Bicontravariant p) =>
p a b -> p a c
rphantom (p s () -> p s s) -> (p a a -> p s ()) -> p a a -> p s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (f :: * -> *). Apply f => (a -> f Any) -> s -> f ())
-> Traversal1 s () a Any
forall a b s t.
(forall (f :: * -> *). Apply f => (a -> f b) -> s -> f t)
-> Traversal1 s t a b
traversal1 (\ a -> f Any
f s
s -> Fold1 s a -> (a -> f Any) -> s -> f ()
forall (f :: * -> *) s a r.
Apply f =>
Fold1 s a -> (a -> f r) -> s -> f ()
traverse1Of_ Optic' p s a
Fold1 s a
a1 a -> f Any
f s
s f () -> f () -> f ()
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Apply f => f a -> f b -> f b
.> Fold1 s a -> (a -> f Any) -> s -> f ()
forall (f :: * -> *) s a r.
Apply f =>
Fold1 s a -> (a -> f r) -> s -> f ()
traverse1Of_ Optic' p s a
Fold1 s a
a2 a -> f Any
f s
s) Optic p s () a Any -> (p a a -> p a Any) -> p a a -> p s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p a a -> p a Any
forall (p :: * -> * -> *) a b c.
(Profunctor p, Bicontravariant p) =>
p a b -> p a c
rphantom)