The codensity monad on a type constructor f is defined by:
newtype C f a = C { unC ∷ forall r. (a → f r) → f r }
It is well known that C f is a monad for any type constructor f (not necessarily covariant). The codensity monad is useful in several ways but it is a complicated type that contains a higher-order function under a universal type quantifier.
My question is, for what f can one show that C f is equivalent to a simpler monad that is defined without type quantifiers?
Some examples where a simplification is possible:
f a = a(the identity functor), for whichC f a = a.f a = r -> a(the Reader monad), for whichC fis the State monad (C f a = r -> (a, r)).f a = (w, a)(the Writer monad), for whichC f a = ((a -> w) -> a, (a -> w) -> w)f a = a -> s(a contravariant functor) and thenC f a = (a -> s) -> s(the continuation monad).f a = a -> a(neither covariant nor contravariant) and theC f a = List a
In the first four of those cases, the type equivalence can be derived from the Yoneda identity: forall r. (a -> r) -> F r = F a when F is a covariant functor. The last case is derived via the Church encoding of the inductive type List.
I looked at some other examples and found that in most cases C f does not seem to be equivalent to anything simpler.
Even if we just take f a = Maybe a the resulting type does not seem to be equivalent to a simpler type expression:
newtype CMaybe a = CMaybe { unCMaybe ∷ forall r. (a → Maybe r) → Maybe r }
The Yoneda identity cannot be used here. My best guess (I have no proof so far) is that CMaybe a = (a -> Bool) -> Bool with some additional laws imposed on the functions of that type. Imposing equations on values can be adequately expressed only within a dependently-typed language.
Can one simplify the codensity monad on Maybe?
Are there other examples of type constructors f where C f can be simplified to a type without type quantifiers?
As mentioned in the comments, a function
C Maybe areturns a bit more information than a boolean because therit returns identifies a single input in the callback, sof kchooses anxsuch thatk xisJust.Simplifying the callback type from
a -> Maybe rtoa -> Bool, we obtain the following dependent function type, written in Agda and in Coq respectively for reference:Proof of equivalence in Agda: https://gist.github.com/Lysxia/79846cce777f0394a6f69d84576a325b
This proves the equivalence of
∀ {r} → (a → Maybe r) → Maybe rand a type without a quantifier:((f : a → Bool) → Maybe (∃[ x ] f x ≡ true)), which is equivalent toq:: (a → Bool) → Maybe awith the restriction thatq(p)equalsJust xonly ifp(x) = true.Note that if
ais finite, thenC Maybe ais also finite. One approach to the problem then is to compute the corresponding cardinality function.You can reinterpret the expression of the cardinality as a type, giving a solution to your problem for types of the form
Finite a -> C f a.You can look it up on the online encyclopedia of integer sequences, to find alternative combinatorial interpretations. Sadly, the relevant sequence doesn't have much information.
If you could find a simpler type for
C f a, with only sums, products (not indexed by the cardinality ofa), and exponentials, this may correspond to a non-trivial combinatorial identity. Conversely, difficulty in finding such a combinatorial identity provides compelling evidence for the non-existence of simple solutions. It also gives a quick way to test a candidate simplification for validity, by comparing its cardinality with the expected one.