-
-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
re-engineering of fs2-data-csv #611
base: main
Are you sure you want to change the base?
Conversation
@mberndt123 Thanks for the PR! I now had a closer look at your proposal, see inline comments below. Overall, there are some interesting ideas, but also some points where I disagree or am unsure about the reasoning. Let's discuss :)
The type params were there for reasons. Your changes fix the header type to
What benefit do you see by sealing them? I can agree to the part of providing nice combinators to create instances, but fail to see the gain of forbidding users to write their own instances if they have special needs.
👍 Agreed. It's on my Wishlist for 2.0, too.
I have to think more about this one. Many use cases won't experience a difference as failing on the headers instead of the first row is little change. It also is limiting, imagine the following dummy example: enum Data {
case A(foo: String) // we could also have some discriminator field in both cases, not just distinct fields
case B(bar: Int)
} If a CSV only contained a column
Yeah, sounds reasonable. Would you mind elaborating on your statement on ADTs though? |
Hi @ybasket, thank you for your review, and apologies for how long it has taken me to respond.
The choice of
It exposes what could be completely opaque implementation details to users, like the representation of a Row. For instance, if you change the type from
An empty CSV row makes as much sense as the number 0, the type
If
Unfortunately I'm somewhat short on time right now, so I'm not sure how much time I'm going to be able to invest here… But maybe I was able to provide some food for thought. |
This PR is meant as a basis for discussion of the kinds of changes that I would like to see in fs2-data-csv 2.0.
My goals are:
CsvRowEncoder
themselves. Instead, there should be a few small, builtin primitive instances and a suitable set of combinators to combine these into larger ones. IdeallyCsvRowDecoder
& friends would besealed
CsvRow
with field names every time we parse a row, the fields can be accessed by index.NonEmptyList
is also an inefficient representation and we can useArray
instead. Given the new sealed, compositional API, we probably don't even need to expose theCsvRow
representation to the user at all, giving us much more flexibility for future evolution of the libraryderives
keywordCsvRowEncoder
, it should be possible to generate the header without having any actual data available. The current model is problematic when serializing algebraic data types (sealed traits)Here's what I've done so far:
NonEmptyList
usage – it doesn't bring any real benefits, but prevents us from writing a correctContravariantMonoidal
instance forCsvRowEncoder
CsvRowDecoder
/CsvRowEncoder
/RowDecoder
/RowEncoder
are now sealed, and suitable typeclass instances are provided to combine smaller encoders/decoders into larger ones. Specifically, there is now aContravariantMonoidal
instance for the*Encoder
type classesAll of this is nowhere near complete. For example, I think the
Applicative
instance forRowDecoder
can be made more compositional, and I'll be happy to discuss that in detail later. There is also noMonad
instance forCsvRowDecoder
yet, which is due to the fact that I'd like to completely process the CSV header up-front and never look at it again while parsing the CSV rows. It's possible to do this using Selective Applicative Functors.Alright, that should be enough to get the discussion started.