A contravariant functor is a Functor : it lifts arrows in the opposite direction, to , and reverses composition. Ordinary functors are covariant. In Haskell: class Contravariant f where contramap :: (b -> a) -> (f a -> f b).
Sources: DaoFP §8.3 (“Contravariant functors”), §8.4 (), §9.6 (contravariant Yoneda); Kittenlab Lecture 12, 14 ( via preimage); 7 Sketches §7.3.1 (presheaves); CTfS §4.6.1, Exercises 4.2.3.2, 4.2.4.4, 4.6.1.5
- Producers vs. consumers (DaoFP): a covariant functor is a producer of
as (turn it into a producer ofbs withfmapanda -> b); a contravariant functor is a consumer ofas (you needb -> a).Predicate a = a -> Boolis contravariant:contramap f (Predicate h) = Predicate (h . f). “In practice, the only non-trivial contravariant functors are variations on function objects.” - Polarity: the return type of a function is in positive (covariant) position, the argument in negative (contravariant) position; nesting in a negative position flips polarities.
Tester a = (a -> Bool) -> Boolhasain double-negative, hence positive, position and is covariant;a -> Bool -> Boolhasanegative. - Examples: the contravariant Hom Functor (” as seen by the world”), whose action is pre-composition; presheaves and the Yoneda Embedding ; the Power Set functor via preimage, (Kittenlab); pullback of upper sets ; the functor of a Sheaf on a topological space.
- Why opposite categories (CTfS §4.6.1): “keeping track of which functors were covariant and which were contravariant was a big hassle”; the opposite category makes every functor covariant. CTfS examples: a continuous map pulls open sets back, , so taking open sets is a functor (CTfS Exercise 4.2.3.2); for jurisdictions , every law respected throughout is respected throughout , so “the set of respected laws” is a functor , not (CTfS Exercise 4.2.4.4). Sheaves are exactly such contravariant assignments that also glue (Sheaf).
- Composing a covariant functor after a contravariant one gives a contravariant functor (DaoFP Exercise 8.5.1).
-- a contravariant functor is a functor out of the opposite category
example {C D : Type} [CategoryTheory.Category C] [CategoryTheory.Category D] :
Type _ := Cᵒᵖ ⥤ D
#check CategoryTheory.yoneda -- C ⥤ (Cᵒᵖ ⥤ Type v): x ↦ Hom(-, x)class Contravariant f where
contramap :: (b -> a) -> (f a -> f b)
newtype Predicate a = Predicate (a -> Bool)
instance Contravariant Predicate where
contramap f (Predicate h) = Predicate (h . f)
newtype Tester a = Tester ((a -> Bool) -> Bool) -- covariant: a is in double-negative position
instance Functor Tester where
fmap f (Tester g) = Tester (\h -> g (h . f))