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)?