Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add IsSumType #133

wants to merge 1 commit into from

Conversation

michaelpj
Copy link

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 before DerivingVia.

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.
@michaelpj
Copy link
Author

Ah well, that answers my question about the CI. I could stick it in some CPP, I guess.

@kosmikus
Copy link
Member

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
Copy link
Member

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 the trans_* 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.

Copy link
Author

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.

@michaelpj
Copy link
Author

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.

@michaelpj
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants