My question arises from first law of monads in Haskell: join . fmap join = join . join
.
In Haskell/Category_theory this law is demonstrated by the following picture:
I am confused by the fact that this example uses instances of types, not the types. Because the objects in category Hask
are types, not their instances.
So I tried to redraw this example with types, and here what I got:
In this picture both arrows (join
and fmap join
) leads to the M(M(X))
. Is this the same object, or there are two different M(M(X))
?
I am confused by the fact that this example uses instances of types, not the types. Because the objects in category Hask are types, not their instances.
The example uses an instance of a class, which is itself a type.
In Haskell, yes this is the same object (type). Instances of the Monad
typeclass have to be type constructors and type constructors are injective. Then, it should be pretty clear that
X = X => M(X) = M(X) => M(M(X)) = M(M(X))
The catch here is that that only means they are the same type, not value. Just because fmap join
and join
can both have their types specialized to Monad m => m (m (m a)) -> m (m a)
does not mean that they do the same thing.
They don't.
ghci> (fmap join) [[[1],[2],[3]]]
[[1,2,3]]
ghci> join [[[1],[2],[3]]]
[[1],[2],[3]]
Not all drawings of categories have to end up being commuting diagrams. :)
From the picture, you can see that fmap join
and join
produce different values of the same type. Thus, they are not the same, even though their composition with join
ultimately produces identical values.
In category theory, an epimorphism is a morphism g
such that f1 . g == f2 . g
implies that f1 == f2
as well. In this case, we can see that join
is not an epimorphism, because although fmap join . join == join. join
, it is not true that fmap join == join
.
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