I haven’t done this before, but I think I see something. Your intuition about adding an argument to Mu is good, but you need to pass it so that Free f matches, i.e. So that f takes two arguments instead of one:
newtype Mu fa = In { out :: f (Mu fa) a }
Mu f should be Functor under the right conditions, which will give you the example you are looking for. What are these conditions? We need:
fmap' :: (a -> b) -> f (Mu fa) a -> f (Mu fb) b
We expect f be functorial in the second argument, so no problem. So what we really need to get
f (Mu fa) b -> f (Mu fb) b ^ ^ +--not varying--+
We can use the instance recursively to get Mu fa -> Mu fb , so we just need f be a functor in its first argument. Hence:
class Bifunctor f where bimap :: (a -> c) -> (b -> d) -> fab -> fcd
Then you can write suitable instances
instance (Functor f) => Bifunctor (FreeF f) ... instance (Bifunctor f) => Functor (Mu f) ...
luqui source share