Andrew Coppin <andrewcop...@btinternet.com> writes: > 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 :: *
Yes, and I already have ideas and plan to write a library containing such a class (not sure whether I'll stick to ATs or MPTCs+fundeps though). > 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. ListLike does this, and I agree that it's a problem. > 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? I've worked out a way around doing this in the current state of the experimental replacement for fgl: define a new class that tries to force the parametrism back into the non-parametric structure. However, since super-class constraints are currently not available the resulting type sigs are very, very ugly: ,---- | class (InductiveGraph (g n e)) => MappableGraph g n e where | | gmap :: (InductiveGraph (g n' e')) => (Context (g n e) -> Context (g n' e')) | -> g n e -> g n' e' | gmap f = fromContexts . map f . toContexts | | nmap :: ( InductiveGraph (g n' e) | , Node (g n e) ~ Node (g n' e) | , EdgeLabel (g n e) ~ EdgeLabel (g n' e)) | => (NodeLabel (g n e) -> NodeLabel (g n' e)) | -> g n e -> g n' e | nmap f = gmap f' | where | f' (Context ei n l eo) = Context ei n (f l) eo | | emap :: ( InductiveGraph (g n e') | , Node (g n e) ~ Node (g n e') | , NodeLabel (g n e) ~ NodeLabel (g n e')) | => (EdgeLabel (g n e) -> EdgeLabel (g n e')) | -> g n e -> g n e' | emap f = gmap f' | where | f' (Context ei n l eo) = Context (applyF ei) n l (applyF eo) | applyF = map (second f) `---- -- Ivan Lazar Miljenovic ivan.miljeno...@gmail.com IvanMiljenovic.wordpress.com _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe