love-haskell / coercible-utils

Utility functions for Coercible types
https://hackage.haskell.org/package/coercible-utils
BSD 3-Clause "New" or "Revised" License
9 stars 3 forks source link

Evaluate whether Newtype should have another superclass constraint #39

Open treeowl opened 4 years ago

treeowl commented 4 years ago

We can either say

class (Coercible n o, O n ~ o) => Newtype n o

or

class Coercible n o => Newtype n o | n -> o

For now, I've gone with the latter, because changing it from a fundep to a superclass constraint seems less likely to break things than going the other way around. In principle, I think I'd rather have the superclass constraint so I can be sure I haven't missed some reason for wanting it. My only concern is that if the Newtype instance doesn't specialize away then we'll have to build a dictionary with two superclass fields instead of just having a newtype-like dictionary around Coercible.

To be honest, my concern is probably far too silly to bother with, and we should just upgrade to a superclass constraint. But I'd feel a bit better about that if I had some code demonstrating that doing so adds value in some meaningful way.

treeowl commented 4 years ago

A horrible way to take advantage of a GHC feature I'd like to see removed:

class Coercible (Silly n o) (Silly o (O n))  => Newtype n o
data Silly x y
type role Silly representational nominal

This compresses the Coercible constraint and the equality constraint into a single Coercible constraint. But of course that's the most horrible possible thing to expose to users.

kozross commented 4 years ago

I think 'upgrade to superclass constraint' is the logically right move. If there are serious performance issues, users can (in the short term) resort to the Wild API, or (in the long term) yell at us about it with their specific use case, so that we have something to work from.