
Currently we have class Functor c where fmap :: (x -> y) -> (c x -> c y) This relies on c having kind * -> *. For example, Bytestring cannot be an instance of Functor. A cleaner solution would be to have something like class Container c where type Element c :: * I then attempted to write class Container c => Functor c where fmap :: (Functor cx, Functor cy, Element cx ~ x, Element cy ~ y) => (x -> y) -> (cx -> cy) However, this fails horribly: The type signature fails to mention c. And even if it did, this type signature still isn't correct: It says that fmap can transform *any* functor into *any* other functor, which is wrong. It seems that we have gained the ability to talk about containers holding any type of value (even hard-coded types or types with class constraints), but lost the ability to refer to a particular "type of" functor without also specifying the element type. Does anybody know a straightforward way to fix this? Or is this just a dead end?