-
Notifications
You must be signed in to change notification settings - Fork 48
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
Add IsSumType #133
base: master
Are you sure you want to change the base?
Add IsSumType #133
Conversation
This is handy for the common case where a datatype is just a tagged union of sub-types. Many instance declarations for such types just consist of dispatching to the instance method for the sub-type. These can be written generically with `IsSumType` and deriving-via.
Ah well, that answers my question about the CI. I could stick it in some CPP, I guess. |
Interesting, thanks. Yes, I think this would be useful to have. |
where | ||
go :: AllZip IsSingletonOf xs xss => NS I xs -> NS (NP I) xss | ||
go (Z x) = Z (x :* Nil) | ||
go (S xss) = S $ go xss |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd much rather have the conversion functions be applications of trans_NS
.
This is simple enough for sumTypeFrom
:
sumTypeFrom :: IsSumType a xs => a -> NS I xs
sumTypeFrom = to . SOP . trans_NS (Proxy :: Proxy IsSingletonOf) (:* Nil)
However, we need the flipped constraint for sumTypeTo
:
sumTypeTo = trans_NS (Proxy :: Proxy (Flip IsSingletonOf)) hd . unSOP . from
This requires the obvious class/instance definition of Flip
, but also means we have to add AllZip (Flip IsSingletonOf) (Code a) xs
to the constraints for IsSumType
.
This is a general annoyance with trans_NP
and AllZip
, the GHC cannot prove one constraint from the other. There are different options here:
- add a version of
AllZip
that expands to both directions, - add a variant
rtrans_*
to thetrans_*
family of functions which works on the reversed constraint, - use explicit dictionary manipulation to turn one constraint into the other.
I'm not sure what's best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't forgotten about this, but it'll take me a while to try either of those, and I certainly don't feel like I have the judgement to say which of your suggested alternatives is better.
I found myself wanting this PR again. I know that the conversion functions don't work the way you'd like, but I wonder if you'd consider accepting the suboptimal version anyway, since it seems like it's not obvious how to make it nicer. |
In case it's motivating: in this case the usecase is someone adding structured logging to HLS, where there is a lot of "this log type is the sum of the log types for all the sub-components, and now I'm going to write a bunch of tedious type class instances that just delegate to each individual type", i.e. exactly the kind of boilerplate that this lets us avoid. |
I found myself wanting this, and it seems like an obvious complement to the tools already in this library. I'm not all that good with
generics-sop
yet, so quite possibly this has a nicer implementation!The test might also be problematic, since it uses
DerivingVia
(but illustrates the usecase I have for this). I don't know whether the test suite runs on versions of GHC from beforeDerivingVia
.