In playing with compositions involving functors & cofunctors, I've run into a conflict in the instances I want to provide. I imagine this sort of problem is well-known, and I'd like to hear what kinds of strategies people apply.
<br><br>Here's a definition of type composition:<br><br><span style="font-family: courier new,monospace;"> newtype O g f a = O { unO :: g (f a) }</span><br><br>and a cofunctor class:<br><br><span style="font-family: courier new,monospace;">
class Cofunctor cof where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> cofmap :: (a -> b) -> (cof b -> cof a)</span><br><br>We can compose functors to get a functor, cofunctors to get a functor, and functor & cofunctor in either order to get a cofunctor.
<br><br><span style="font-family: courier new,monospace;"> instance (Functor g, Functor f) => Functor (O g f) where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
fmap h (O gf) = O (fmap (fmap h) gf)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> instance (Cofunctor g, Functor f) => Cofunctor (O g f) where
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> cofmap h (O gf) = O (cofmap (fmap h) gf)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> instance (Functor g, Cofunctor f) => Cofunctor (O g f) where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> cofmap h (O gf) = O (fmap (cofmap h) gf)
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> instance (Cofunctor g, Cofunctor f) => Functor (O g f) where</span>
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> fmap h (O gf) = O (cofmap (cofmap h) gf)</span><br><br>I've wanted all four of those instances. The problem is that instance selection (in GHC at least) ignores the contexts. Without context, the first and fourth instances conflict, as do the second and third. Thus I statically choose two of the four rules and comment out the other two. Depending on my application, sometimes I like my choices, and sometimes I don't.
<br><br>Are there work-arounds to get the flexibility I want out of GHC?<br><br>Is it plausible to improve instance selection to use contexts? I imagine doing so would require some kind of backtracking search.<br><br>Thanks, - Conal
<br><br><br><br>