So I understand the basic algebraic interpretation of types:
Either a b ~ a + b (a, b) ~ a * b a -> b ~ b^a () ~ 1 Void ~ 0 -- from Data.Void ... and that these relations are true for concrete types, like Bool, as opposed to polymorphic types like a. I also know how to translate type signatures with polymorphic types into their concrete type representations by just translating the Church encoding according to the following isomorphism:
(forall r . (a -> r) -> r) ~ a So if I have:
id :: forall a . a -> a I know that it does not mean id ~ a^a, but it actually means:
id :: forall a . (() -> a) -> a id ~ () ~ 1 Similarly:
pair :: forall r . (a -> b -> r) -> r pair ~ ((a, b) -> r) - > r ~ (a, b) ~ a * b Which brings me to my question. What is the "algebraic" interpretation of this rule:
(forall r . (a -> r) -> r) ~ a For every concrete type isomorphism I can point to an equivalent algebraic rule, such as:
(a, (b, c)) ~ ((a, b), c) a * (b * c) = (a * b) * c a -> (b -> c) ~ (a, b) -> c (c^b)^a = c^(b * a) But I don't understand the algebraic equality that is analogous to:
(forall r . (a -> r) -> r) ~ a
This is the famous Yoneda lemma for the identity functor.
Check this post for a readable introduction, and any category theory textbook for more.
Briefly, given f :: forall r. (a -> r) -> r you can apply f id to get an a, and conversely, given x :: a you can take ($x) to get forall r. (a -> r) -> r.
These operations are mutually inverse. Proof:
Obviously ($x) id == x. I will show that
($(f id)) == f,
since functions are equal when they are equal on all arguments, let's take x :: a -> r and show that
($(f id)) x == f x i.e.
x (f id) == f x.
Since f is polymorphic, it works as a natural transformation; this is the naturality diagram for f:
f_A Hom(A, A) → A (x.) ↓ ↓ x Hom(A, R) → R f_R So x . f == f . (x.).
Plugging identity, (x . f) id == f x. QED
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With