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

Implement a new typeclass hierarchy #59

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

endgame
Copy link
Contributor

@endgame endgame commented Oct 23, 2021

My take on the hierarchy hashed out at the end of the comment thread on #54. Given that breaking changes are necessary, this is fairly aggressive about breaking them to bring more consistency to the library. I am happy to walk things back if necessary.

Defines:

  • Profunctor => SemiproductProfunctor => ProductProfunctor

    This operates on tuples, and gives the operations from the
    Applicative(Apply) and Divisible(Divise) typeclasses.

  • Profunctor => SemisumProfunctor => SumProfunctor

    This operates on Eithers, and gives the operations from the
    Decidable (Decide/Conclude) typeclasses.

Breaking changes:

  • purePP -> pureP for consistency with everything else.
  • empty -> unitP for consistency with voidP.
  • (***!) moved to SemiproductProfunctor
  • (+++!) moved to SemisumProfunctor
  • New superclasses introduced - downstream will need to write more instances.

Other changes:

  • Cleaned up a bunch of compiler/haddock warnings.
  • Instances for Forget r
  • A few other relaxations of overly-tight constraints ((***$) only needs a Profunctor constraint, some instances could use less strict classes, etc.)

Open questions:

  • Are you happy with these {class,operator,function} names?
  • We could keep the current operator names around in the subclass as deprecated aliases (like how return has hung around in Monad). Should we do this?
  • Should we depend on semigroupoids? The 5.3.6 release added the contravariant hirerarchy, and the Semi-classes are less useful if we still use Applicative/Divisible/Decidable instances for this stuff.

Remaining work:

  • Fix up the makeAdaptorAndInstance family of functions to create Semi... instances. If this is the main source of instances downstream, breaking changes may not be so great (apart from intermediate libraries like opaleye).
  • Changelog
  • Tests
  • Fix up the remaining haddocks to clear up Haddock garbled #52
  • Maybe bring in some operators from Considerations for bidirectional parsing #51?

Closes #54

@endgame
Copy link
Contributor Author

endgame commented Oct 23, 2021

This is good to review but not good to merge (tests do not compile, makeAdaptorAndInstance likely broken). But there's no point doing that work until we're happy with the API.

@endgame endgame force-pushed the semi-sum-and-product-profunctors branch from 5e74922 to 560680f Compare October 23, 2021 08:02
@endgame endgame force-pushed the semi-sum-and-product-profunctors branch from 560680f to a025611 Compare October 23, 2021 08:05
@tomjaguarpaw
Copy link
Owner

The things that are easy to respond to immediately:

  • We could keep the current operator names around in the subclass as deprecated aliases (like how return has hung around in Monad). Should we do this?

    Yes!

  • A few other relaxations of overly-tight constraints ((***$) only needs a Profunctor constraint, some instances could use less strict classes, etc.)

    They can be merged without bumping the major version, can't they? If so please submit those in a separate PR. In fact putting them in a separate PR is probably a good idea anyway. They're easier to merge.

@tomjaguarpaw
Copy link
Owner

If so please submit those in a separate PR.

In fact, I'll do some separation and then get back to you.

@tomjaguarpaw tomjaguarpaw force-pushed the semi-sum-and-product-profunctors branch from a025611 to 31be14b Compare October 23, 2021 09:39
@tomjaguarpaw
Copy link
Owner

I split this up a bit, merged some to rc, and took the liberty of force-pushing to your branch.

@endgame
Copy link
Contributor Author

endgame commented Oct 23, 2021

No problem at all. What do you think we should do wrt operators? If you want to keep the old names on the non-Semi classes for backwards compat, we need new versions of the following operators to put in the Semi classes:

  • (***!) :: SemiproductProfunctor p => p a c -> p b d -> p (a, b) (c, d) (tupling)
  • (****) :: SemiproductProfunctor p => p x (a -> b) -> p x a -> p x b ((<*>) analogue)
  • (+++!) :: SemisumProfunctor p => p a c -> p b d -> p (Either a b) (Either c d) (eithering)

I think we want something that has a consistent visual language, and has some kind of "wings" we can drop off either side (analogues to (<*) and (*>)), so we can provide things like:

(-?) :: SemiproductProfunctor p => p a b -> p () () -> p a b
(?-) :: SemiproductProfunctor p => p () () -> p a b -> p a b

The <_> shape usually means covariant functors (<$>, <*>, etc); the >_< shape means contravariant functors (>$<, >*<, etc). Because we have covariant and contravariant type variables, neither feel appropriate. I had (-*-) in one of my PRs, but I'm not sure how much I like it here; maybe (=*=) and (=+=)? That would leave the -_- shape free for invariant or monoidal functors or something.

Hoogle says nobody's really using operator names like (=_=), with the exception of conduit's (=$=), but that's deprecated anyway. Ah, but (+=) and (*=) show up in lens, and ($=) in StateVar. Maybe not, then?

Do you have any thoughts here?

@tomjaguarpaw
Copy link
Owner

Oh sorry, I misread. I'm happy with the old operators going to new classes. I would like to keep any completely deleted symbols around as deprecated though (e.g. empty)

@endgame
Copy link
Contributor Author

endgame commented Oct 23, 2021

OK, I can fix that. How do you feel about them being moved out of the typeclass, or would you rather keep them as methods?

@tomjaguarpaw tomjaguarpaw force-pushed the semi-sum-and-product-profunctors branch from 31be14b to 2a22126 Compare October 23, 2021 10:39
@tomjaguarpaw
Copy link
Owner

This is nice, thanks!

would you rather keep them as methods?

Yes, keep them as methods for now. We can note that they are deprecated now, actually deprecate them later, and remove them even later. It's best to do this in stages.

A couple of minor requests:

  • Don't remove the Monoid and Applicative imports. They're needed to support back to 8.0.

  • Please replace the explicit imports rather than importing <type>(..). I prefer to see exactly what's coming from where.

@tomjaguarpaw
Copy link
Owner

I suggest you rework the final commit as you wish and I'll have a look at it when you've got something you're happy with.

@tomjaguarpaw
Copy link
Owner

And where it makes sense please split things into smaller commits. For example adding the instance for Forget can be added as a separate commit after the main one.

@endgame endgame force-pushed the semi-sum-and-product-profunctors branch from f124392 to 42681d9 Compare November 28, 2021 06:25
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