A Divisible contravariant functor is the contravariant analogue of Applicative.
Continuing the intuition that Contravariant functors consume input, a Divisible contravariant functor also has the ability to be composed "beside" another contravariant functor.
Serializers provide a good example of Divisible contravariant functors. To begin let's start with the type of serializers for specific types:
newtype Serializer a = Serializer { runSerializer :: a -> ByteString }
This is a contravariant functor:
instance Contravariant Serializer where
contramap f s = Serializer (runSerializer s . f)
That is, given a serializer for a (s :: Serializer a), and a way to turn
bs into as (a mapping f :: b -> a), we have a serializer for b:
contramap f s :: Serializer b.
Divisible gives us a way to combine two serializers that focus on different
parts of a structure. If we postulate the existance of two primitive
serializers - string :: Serializer String and int :: Serializer Int, we
would like to be able to combine these into a serializer for pairs of
Strings and Ints. How can we do this? Simply run both serializers and
combine their output!
data StringAndInt = StringAndInt String Int
stringAndInt :: Serializer StringAndInt
stringAndInt = Serializer $ \(StringAndInt s i) ->
let sBytes = runSerializer string s
iBytes = runSerializer int i
in sBytes <> iBytes
divide is a generalization by also taking a contramap like function to
split any a into a pair. This conveniently allows you to target fields of
a record, for instance, by extracting the values under two fields and
combining them into a tuple.
To complete the example, here is how to write stringAndInt using a
Divisible instance:
instance Divisible Serializer where
conquer = Serializer (const mempty)
divide toBC bSerializer cSerializer = Serializer $ \a ->
case toBC a of
(b, c) ->
let bBytes = runSerializer bSerializer b
cBytes = runSerializer cSerializer c
in bBytes <> cBytes
stringAndInt :: Serializer StringAndInt
stringAndInt =
divide (\(StringAndInt s i) -> (s, i)) string int
Instances32Divisible, …
Divisible SettableStateVarDefined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible ComparisonDefined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible EquivalenceDefined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible PredicateDefined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible ProxyDefined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible U1Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (MaybeT m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleMonoid r => Divisible (Op r)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible f => Divisible (Alt f)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible f => Divisible (Rec1 f)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible f => Divisible (WrappedContravariant f)Defined in invariant-0.6.4 · Data.Functor.InvariantDivisible f => Divisible (Backwards f)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible f => Divisible (IdentityT f)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible f => Divisible (Reverse f)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (ExceptT e m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (ReaderT r m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (StateT s m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (StateT s m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (WriterT w m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (WriterT w m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleMonoid m => Divisible (Const m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleMonoid m => Divisible (Constant m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.Divisible(Divisible f, Divisible g) => Divisible (Day f g)Defined in kan-extensions-5.2.7 · Data.Functor.Contravariant.Day(Divisible f, Applicative g) => Divisible (ComposeCF f g)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.Compose(Applicative f, Divisible g) => Divisible (ComposeFC f g)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.Compose(Divisible f, Divisible g) => Divisible (Product f g)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.Divisible(Divisible f, Divisible g) => Divisible (f :*: g)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible f => Divisible (M1 i c f)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (RWST r w s m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.DivisibleDivisible m => Divisible (RWST r w s m)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.Divisible(Applicative f, Divisible g) => Divisible (Compose f g)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.Divisible(Applicative f, Divisible g) => Divisible (f :.: g)Defined in contravariant-1.5.5 · Data.Functor.Contravariant.Divisible