module Contravariant.Extras
(
module Contravariant.Extras.Contrazip,
module Contravariant.Extras.ContrazipLifting,
(>*<),
contramany,
Supplied (..),
)
where
import Contravariant.Extras.Contrazip
import Contravariant.Extras.ContrazipLifting
import Contravariant.Extras.Prelude hiding ((<>))
import Data.Semigroup (Semigroup ((<>)))
{-# INLINE (>*<) #-}
(>*<) :: (Divisible f) => f a -> f b -> f (a, b)
>*< :: forall (f :: * -> *) a b. Divisible f => f a -> f b -> f (a, b)
(>*<) =
forall (f :: * -> *) a b. Divisible f => f a -> f b -> f (a, b)
divided
contramany :: (Decidable f) => f a -> f [a]
contramany :: forall (f :: * -> *) a. Decidable f => f a -> f [a]
contramany f a
f =
f [a]
loop
where
loop :: f [a]
loop =
forall (f :: * -> *) a b c.
Decidable f =>
(a -> Either b c) -> f b -> f c -> f a
choose forall {a}. [a] -> Either (a, [a]) ()
chooser f (a, [a])
cons forall {f :: * -> *} {a}. Divisible f => f a
nil
where
chooser :: [a] -> Either (a, [a]) ()
chooser =
\case
a
head : [a]
tail ->
forall a b. a -> Either a b
Left (a
head, [a]
tail)
[a]
_ ->
forall a b. b -> Either a b
Right ()
cons :: f (a, [a])
cons =
forall (f :: * -> *) a b c.
Divisible f =>
(a -> (b, c)) -> f b -> f c -> f a
divide forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id f a
f f [a]
loop
nil :: f a
nil =
forall (f :: * -> *) a. Divisible f => f a
conquer
data Supplied divisible
= forall input. Supplied (divisible input) input
instance (Divisible divisible) => Semigroup (Supplied divisible) where
Supplied divisible input
divisible1 input
input1 <> :: Supplied divisible -> Supplied divisible -> Supplied divisible
<> Supplied divisible input
divisible2 input
input2 =
forall (divisible :: * -> *) input.
divisible input -> input -> Supplied divisible
Supplied divisible (input, input)
divisible3 (input, input)
input3
where
divisible3 :: divisible (input, input)
divisible3 =
forall (f :: * -> *) a b c.
Divisible f =>
(a -> (b, c)) -> f b -> f c -> f a
divide forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id divisible input
divisible1 divisible input
divisible2
input3 :: (input, input)
input3 =
(input
input1, input
input2)
instance (Divisible divisible) => Monoid (Supplied divisible) where
mempty :: Supplied divisible
mempty =
forall (divisible :: * -> *) input.
divisible input -> input -> Supplied divisible
Supplied forall (f :: * -> *) a. Divisible f => f a
conquer ()
mappend :: Supplied divisible -> Supplied divisible -> Supplied divisible
mappend =
forall a. Semigroup a => a -> a -> a
(<>)