[Haskell-cafe] Is it possible to get the selector functions when defining a generic class?

Chris Kahn chris at kahn.pro
Thu Nov 24 19:19:56 UTC 2016


Thanks for this! Seems like that's what I want. I didn't know about
generics-sop.

Although something about the code for the enumerator types doesn't
compile and throws this GHC panic:

ghc: panic! (the 'impossible' happened)
  (GHC version 8.0.1 for x86_64-unknown-linux):
	print_equality ~

Do you think it's related to this ticket?
(https://ghc.haskell.org/trac/ghc/ticket/12041)

But at least, when I remove the definitions for enumerated types it
compiles, so I'll test it out and see how this is working.


On Thu, Nov 24, 2016, at 04:12 AM, Andres Loeh wrote:
> Hi Chris.
> 
> Here's a proof-of-concept implementation using generics-sop:
> 
> https://gist.github.com/kosmikus/83a644fcaa620b5f5505d48540a5f155
> 
> It's entirely untested, but it should in principle work, and it should
> demonstrate how you can do the contramap/selector stuff generically,
> so perhaps it helps.
> 
> Cheers,
>   Andres
> 
> 
> On Thu, Nov 24, 2016 at 4:17 AM, Chris Kahn <chris at kahn.pro> wrote:
> > Aaaand you'll get mine twice since I forgot to reply-all the first time :)
> >
> > Sure, so in postgresql-simple there are two classes for automatically
> > generating functions that encode/decode database rows, `FromRow` and
> > `ToRow`. In the Hasql library--another postgres library--the encoders
> > and decoders must be written by hand for each user-defined type. I want
> > to write a class that will automatically generate these.
> >
> > I successfully wrote a `FromRow` class that can generate Hasql's `Row`
> > type, since it's basically identical to what's in postgresql-simple's
> > `FromRow`. But in Hasql the encoder type, Params, is contravariant and
> > encoders are defined like:
> >
> >     personEncoder :: Params Person
> >     personEncoder = contramap name (value text) <>
> >                     contramap age (value int)
> >
> > The `value text` part can be determined based on the type information,
> > but it's also expecting a matching selector function. I'm at a total
> > loss for how I could generate something like this.
> >
> >
> >
> > On 11/23/2016 10:06 PM, David Feuer wrote:
> >> Sorry if anyone gets this twice; the first copy somehow went to a
> >> non-existent Google Groups version of haskell-cafe.
> >>
> >> GHC.Generics doesn't offer any built-in support for such things. It
> >> *looks* like there *might* be some support in packages built around
> >> generics-sop. When you're working directly with GHC.Generics, the
> >> notion of a record barely even makes sense. A record is seen as simply
> >> a possibly-nested product. For example, ('a','b','c') will look
> >> *approximately* like 'a' :*: ('b'  :*: 'c'). You're generally not
> >> "supposed" to care how large a record you may be dealing with, let
> >> alone what field names it has. May I ask what you're actually trying
> >> to do? Your specific request sounds peculiarly un-generic.
> >>
> >> On Wed, Nov 23, 2016 at 9:52 PM,  <chris at kahn.pro> wrote:
> >>> Hey all!
> >>>
> >>> I'm trying to understand what's going on in GHC.Generics and defining a
> >>> generic class... I understand that there's a `Selector` class and `selName`
> >>> function that can get the name of a selector, but is there a way to access
> >>> the selector function itself? The documentation conveniently avoids examples
> >>> involving records and is otherwise quite barren.
> >>>
> >>> So if I have a data type like...
> >>>
> >>> data Person = Person
> >>>     { name :: String
> >>>     , age :: Int
> >>>     } deriving Generic
> >>>
> >>> instance MyTypeClass Person
> >>>
> >>> I want my generic implementation of MyTypeClass to be able to access each
> >>> selector function in the record, f :: Person -> String, g :: Person -> Int,
> >>> etc.
> >>>
> >>> Chris
> >>>
> >>> _______________________________________________
> >>> Haskell-Cafe mailing list
> >>> To (un)subscribe, modify options or view archives go to:
> >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> >>> Only members subscribed via the mailman list are allowed to post.
> > _______________________________________________
> > Haskell-Cafe mailing list
> > To (un)subscribe, modify options or view archives go to:
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > Only members subscribed via the mailman list are allowed to post.


More information about the Haskell-Cafe mailing list