I got stuck on this tutorial https://ocharles.org.uk/blog/posts/2014-04-26-constructing-generically.html when trying verify the type of mk
for l :*: r
when l = K1 _ a
, fl = ((->) a)
and r = K1 _ b
, fr = ((->) b)
class Functor f => Mk rep f | rep -> f where
mk :: f (rep a)
instance Mk (K1 i c) ((->) c) where
mk = \x -> K1 x
instance (Mk l fl, Mk r fr) => Mk (l :*: r) (Compose fl fr) where
mk = Compose (fmap (\l -> fmap (\r -> l :*: r) mk) mk)
Now by the type class definition mk :: f (rep _)
and we have f = Compose ((->) a) ((->) b) = * -> a -> b -> *
and rep _ = l:*:r
and so mk :: a -> b -> l:*:r
. This is what I expected.
However, I think (fmap (\l -> fmap (\r -> l :*: r) mk) mk) :: a -> b -> l:*:r
and I cant see how using this as a first argument to Compose :: forall k k1. (k -> *) -> (k1 -> k) -> k1 -> *
will ever give back the expected signature of mk
??
Also, I found this answer https://stackoverflow.com/a/35424427/11998382 helpful but I got lost at
f :: Compose ((->) a) ((->) b) (f r)
g :: Compose ((->) c) ((->) d) (g r)
mk f g :: Compose (Compose ((->) a) ((->) b)) (Compose ((->) c) ((->) d)) ((:*:) f g r)
Did they mean fl :: Compose ((->) a) ((->) b) (f r)
or mk f :: Compose ((->) a) ((->) b) (f r)
?