haskell-hvr / cassava

A CSV parsing and encoding library optimized for ease of use and high performance
http://hackage.haskell.org/package/cassava
BSD 3-Clause "New" or "Revised" License
222 stars 105 forks source link

Deriving FromField/ToField instances? #206

Open stevladimir opened 2 years ago

stevladimir commented 2 years ago

There is an API for deriving ToRecord/FromRecord instances, but none for ToField/FromField. I looked through opened and closed issues and was unable to find any discussion regarding this.

Are there any deep reason's for not having generic instances for ToField/FromField?

andreasabel commented 2 years ago

Over to @tibbe and @hvr ...

phadej commented 2 years ago

How these instances would work? ToField/ FromField instances are "leaf"s: parsing a cell value into haskell value. What Generics would do there? I can think of deriving for newtypes, but these can be derived using newtype strategy anyway.

stevladimir commented 2 years ago

There can't exist reasonable encoding for all cases, e.g. for product types. But it exists for subset of sum types with constructors of 0- or 1-arity:

data Foo = Foo

data Foo = Bar | Baz Int

It's similar to UntaggedValue encoding from aeson. IIRC it should be possible to provide instances only for those cases without any dirty hacks.

phadej commented 2 years ago

Enum case makes sense. 1-arity is suspicious.

I'd suggest defining newtypes to be used with deriving via so the user tells what they want (instead of using clever generics trying to guess). That has an additional benefit that deriving mechanisms stay independent.

FWIW, I plan to make that change to aeson (in year or so, I'm not keen to break people too often).

stevladimir commented 2 years ago

Enum case makes sense. 1-arity is suspicious.

I'd suggest defining newtypes to be used with deriving via so the user tells what they want (instead of using clever generics trying to guess). That has an additional benefit that deriving mechanisms stay independent.

FWIW, I plan to make that change to aeson (in year or so, I'm not keen to break people too often).

I think we can select precisely which instances to allow (see PR). It works only for 'single nullary' or 'sum with 0,1 constructors' types and doesn't allow deriving for newtypes. Actually, another option could be not adding default method at all, so user would have to write instance explicitly in case of such need.

stevladimir commented 2 years ago

FWIW, I plan to make that change to aeson (in year or so, I'm not keen to break people too often).

Yeah, I like the idea. Current behavior is slightly confusing