magnolia icon indicating copy to clipboard operation
magnolia copied to clipboard

Derivation with "exists" semantics

Open joroKr21 opened this issue 8 years ago • 3 comments

What I mean is what if to create a type class for the whole case class / sealed trait I only need the instance for one field / subtype (or a subset of all fields / subtypes)? Like finding a field of some type deep within the structure.

E.g. Default only uses the first subtype instance. In fact it could be any instance. The rest of the subtype instances don't even need to exist.

I'm not sure if #46 would enable this?

joroKr21 avatar Dec 06 '17 12:12 joroKr21

I think I understand, and I think something would be possible with #46, though if you have a concrete example, I would probably be more certain that I'm understanding correctly!

propensive avatar Jan 02 '18 10:01 propensive

One example is Default for a sealed trait:

sealed trait MaybeDate
case class ADate(date: Date) extends MaybeDate
case object NoDate extends MaybeDate

If I don't have a default Date I should still have a default MaybeDate by virtue of NoDate.

In general for any coproduct A :+: B :+: C :+: CNil there should be a Default instance whenever there exists a default instance for at least one of A, B or C. With shapeless I can express this like so (note the missing instance for CNil):

implicit def defaultLeft[L, R <: Coproduct](implicit L: Default[L]): Default[L :+: R] = ...
implicit def defaultRigth[L, R <: Coproduct](implicit R: Default[R]): Default[L :+: R] = ...

joroKr21 avatar Jan 02 '18 15:01 joroKr21

That's a pretty clear example, thanks. I think we can offer a dispatch parameter which provides a non-empty list of derived typeclasses. (This will probably make more sense when I finally merge #46.) It needs a bit of reworking to ensure derivation continues even when not every branch of the coproduct can be derived, but should be doable.

propensive avatar Jan 02 '18 21:01 propensive