I'm going mental with Chapter 8 from Category Theory for Programmers.
In section 8.3, Bartosz defines this type
newtype BiComp bf fu gu a b = BiComp (bf (fu a) (gu b))
Here, if I'm understanding a bit of Haskell, bf
, fu
, and gu
are type constructors, bf
of kind (* -> *) -> (* -> *) -> * -> * -> *
, and fu
and gu
of kind * -> *
(just like Maybe
or []
), whereas a
, and b
are general types of kind *
; BiComp
on the left of =
is a type constructor of kind to long to write, whereas BiComp
on the right is a value constructor, so it's of type (bf (fu a) (gu b)) -> BiComp bf fu gu a b
.
Then the author makes BiComp
a bifunctor in a
and b
, provided that the type constructor parameter bf
is a Bifunctor
too, and that the type constructors fu
and gu
are Functor
s:
instance (Bifunctor bf, Functor fu, Functor gu) => Bifunctor (BiComp bf fu gu) where
bimap f1 f2 (BiComp x) = BiComp ((bimap (fmap f1) (fmap f2)) x)
So far so good, all seems reasonable to me at this point. Except that using the same name for the type constructor and value constructor is probably getting me lost.
Now I'm tempted to make the following observations:
- the
bimap
on the right of the definition is the one leveraging the constraints: it's thebimap
that is assumed as defined in theBifunctor
instance of whatever type contructorbf
really is, therefore thisbimap
has type(a -> a') -> (b -> b') -> bf a b -> bf a' b'
; I think this is less interesting than the following, because it's after all just the signature ofbimap
for theBifunctor
typeclass
presented in 8.1; - the
bimap
on the left, instead, is the one we are defining to makeBiComp
aBifunctor
in its 4th and 5th parameters; and the argumentsf1
andf2
are function that have to act on entities of type which are those 4th and 5th parameters ofBiComp
; therefore, thisbimap
's type is(a -> a') -> (b -> b') -> BiComp bf fu gu a b -> BiComp bf fu gu a' b'
.
Is this correct?
If so, then I don't understand the following
bimap :: (fu a -> fu a') -> (gu b -> gu b') -> bf (fu a) (gu b) -> bf (fu a') (gu b')
because this is the type of the bimap
on the right, the one I wrote in the bullet point above, except that it's written with a
= fu a
, a'
= fu a'
, and so on.
Am I missing something (or overthinking...)?