spartanz / schemaz

A purely-functional library for defining type-safe schemas for algebraic data types, providing free generators, SQL queries, JSON codecs, binary codecs, and migration from this schema definition
https://spartanz.github.io/schemaz
Apache License 2.0
164 stars 18 forks source link

Iso schemas aren't enough #33

Open vil1 opened 5 years ago

vil1 commented 5 years ago

With only IsoSchema, we cannot define schemas such as "dates represented as JSON strings":

val dateSchema = iso(prim(JsonString), stringToDate)

Because we cannot implement a correct Iso that goes from String to Date. We could go from String to Option[Date] with an isomorphism, but that of course doesn't cover all the use cases.

A simple solution would be to add a PrismSchema to the schema GADT, same as IsoSchema but with a Prism instead of an Iso. Interpreter for covariant functors would then use this new node to handle errors and contravariant ones would use it the same way they use IsoSchema.

If we go down that road, the public API should be adapted carefully. I'd rather not add a prism combinator, because it would be easily confused with prim. Ideally, I'd like to have a unique combinator for "a schema seen through an optic" that would build an IsoSchema or a PrismSchema depending on the argument it is passed, be it an Iso or a Prism.

julienrf commented 4 years ago

Note that by returning Option[Date] you can not provide helpful error messages in decoder interpreters. You will have to return something like Validated[Date].