Skip to content

Add an Endofunctor to the context of Functor (Covariant functor) and Contravariant

Motivation

There's a use case for a typeclass for codecs and probably other types which are both covariant and contravariant endofunctors. It is a typeclass like Profunctor but where the contravariant and covariant sides share the same type at all times (because it will have only one type parameter). For example a codec can be mapped so that it (de)serialises a different type.

Proposal

--|
-- specialisation of a profunctor where both left and right share the same type
--  a codec might be an instance of this because it is both covariant and contravariant
-- but a codec would be an instance of neither Functor nor Contravariant because their
-- map functions will always map one side to _|_
-- In a way this models the configuration of a mutation pipeline with tuning/continuations/routing depending
-- on the type.
--
-- It's in the context of Functor and Contravariant because endomap is fully defined for each
-- of them.
--
-- I can't think of what laws it might have apart from the below but I'm half convinced
-- this is an important typeclass.
--
-- I'm thinking things like:
-- @endomap f_retraction g_retraction . endomap f g@ is never extensionally inequal to id
--  (bottom not witnessing inequality), that is, f and f_retraction can be _|_ as well as total functions.
-- @endomap f g . endomap h i = endomap (f . h) (g . i)@
--
-- maybe someone can suggest something else?
--
-- Also important because it extends the landscape so we can mentally connect to things like sets of data items.
class Endofunctor f where
    endomap :: (b -> a) -> (a -> b) -> f a -> f b

--|
-- Laws:
-- in addition to the existing laws
-- @endomap f g x = endomap h g x@, for all f and h
-- @endomap f g x = fmap g x@
-- @endomap undefined g x@ is no less defined than @endomap f g x@ for any f
class Endofunctor f => Functor f ...

--|
-- Laws:
-- in addition to the existing laws
-- @endomap f g x = endomap f h x@, for all g and h
-- @endomap f g x = contramap f x@
-- @endomap f undefined x@ is no less defined than @endomap f g x@ for any g
class Endofunctor f => Contravariant f ...

Please say if I should implement it and do a merge request.

Edited by code5hot
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information