div package:rebase

integer division truncated toward negative infinity WARNING: This function is partial (because it throws when 0 is passed as the divisor) for all the integer types in base.
Generalisation of div to any instance of Real
simultaneous div and mod WARNING: This function is partial (because it throws when 0 is passed as the divisor) for all the integer types in base.
Generalisation of divMod to any instance of Real
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