[Haskell-cafe] I confused myself with generics, and now I confused ghc too

Ari Rahikkala ari.rahikkala at gmail.com
Mon Jul 18 15:42:58 CEST 2011


I want to implement generic comparison on top of syb-with-class, and
based on looking at syb, it seems I could base it on something like
gzipWithQ from syb's Data.Generics.Twins. However, there's no
Data.Generics.SYB.WithClass.Twins. So I set out to see if I can write
one myself (well, one with just enough stuff to support gzipWithQ
anyway) Here's what I've got so far: http://hpaste.org/49168

The problem is that GHCi seems to be somewhat confused, or at least
confusing, about the type of gzipWithQ here. When I ask with :t, it
reports the type as:

gzipWithQ
  :: (Data ctx a2, Data ctx a3, Data ctx a) =>
     Proxy ctx
     -> (forall a0.
         Data ctx a0 =>
         a0 -> forall a1. Data ctx a1 => a1 -> r)
     -> a2
     -> a3
     -> [r]

If I actually replace gzipWithQ's annotated type with this, GHCi will
reject the program. And in any case with GenericQ being defined as
"type GenericQ ctx r = Data ctx a => a -> r", isn't this closer to
gzipWithQ's type with the type synonyms expanded?

gzipWithQ :: forall ctx a r.
             Data ctx a =>
             Proxy ctx
          -> (Data ctx a0 => a0 -> (Data ctx a1 => a1 -> r))
          -> (Data ctx a2 => a2 -> (Data ctx a3 => a3 -> [r]))

(GHCi accepts this as gzipWithQ's type so I assume it's the same one.
I assume those class constraints after the => come with implicit
foralls? Because it seems to mean the same thing if I put foralls in
there)

I have no idea how to even start figuring out how to make gzipWithQ
and its type work. I only got this far by copying code from
Data.Generics.Twins and passing down the proxy parameter and/or
context type parameter (is it even possible for this approach to
work?). What I can tell is that GHCi will still change the type like
that even if gzipWithQ = undefined, so I'll have to change the type
and not just the body of the function. Is this the kind of thing that
all those newtypes in Data.Generics.Twins are for? Should I read up on
type theory?



More information about the Haskell-Cafe mailing list