-
Notifications
You must be signed in to change notification settings - Fork 10
Replace explicit wrapping and unwrapping of newtypes by coercions #22
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
Replace explicit wrapping and unwrapping of newtypes by coercions #22
Conversation
src/Data/Newtype.purs
Outdated
class Newtype t a | t -> a where | ||
wrap :: a -> t | ||
unwrap :: t -> a | ||
class (Coercible t a, Coercible a t) <= Newtype t a | t -> a |
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.
Isn't Coercible
symmetric? What's the thinking behind giving two Coercible
superclasses instead of just one and letting the compiler solve the other as needed—or does that not work?
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.
Computing subgoals is indeed symmetric, the subgoals of Coercible a b
are the same than the subgoals of Coercible b a
, but the compiler doesn’t deduce Coercible b a
from Coercible a b
.
This means that we need Newtype t a
to imply both Coercible t a
and Coercible a t
for unwrap
and wrap
to compile:
module Example where
import Safe.Coerce (coerce)
import Prim.Coerce (class Coercible)
class Coercible t a <= Newtype t a | t -> a
wrap :: forall t a. Newtype t a => a -> t
wrap = coerce
Error found:
in module Example
at Example.purs:9:8 - 9:14 (line 9, column 8 - line 9, column 14)
No type class instance was found for
Prim.Coerce.Coercible a0
t1
while checking that type forall (a :: Type) (b :: Type). Coercible a b => a -> b
is at least as general as type a0 -> t1
while checking that expression coerce
has type a0 -> t1
in value declaration wrap
where t1 is a rigid type variable
bound at (line 9, column 8 - line 9, column 14)
a0 is a rigid type variable
bound at (line 9, column 8 - line 9, column 14)
See https://github.com/purescript/documentation/blob/master/errors/NoInstanceFound.md for more information,
or to contribute content related to this error.
This is something we might be able to do though, I’ll look into it.
Is there a particular reason not to do this now? I think if we're going to do it at all, then the sooner the better. |
I’d like to release this with the v0.14.0 too but this depends on and implies a few things:
|
Right, ok, I didn't realise we'd have to do all that stuff too. In that case I think we should leave this out for now. If we manage to do all those things before we're ready to release v0.14.0 then that's fine, but otherwise I don't think this is an important enough change to hold v0.14.0 up. |
5d09df3
to
fb2d6c0
Compare
Of the PRs @kl0tl mentioned above that need to be merged before this PR can be merged, only purescript/purescript#3927 hasn't yet been merged (but looks like it will be soon). |
I think purescript/purescript#3927 isn't even a hard requirement for merging this, it's just a change to make certain compiler errors more helpful, so I'd be in favour of going ahead and merging this now. |
Do we need to rebase this on top of current |
I think so, yes. |
fb2d6c0
to
cb8d91e
Compare
CI is failing with this error:
|
That will probably be because the Multiplicative constructor is not in scope, we’ll need to import it in that module. |
This adds
Coercible
superclasses toNewtype
in order to implement most combinators withcoerce
.Newtype constructors have to be exported for them to be unwrapped when solving
Coercible
constraints so this means thatNewtype
instances for types with hidden constructors won’t be usable anymore outside of their module of definition. This is mitigated by purescript/purescript#3907 which emits a warning for such types (this warning would be turned into an error by the pull request updating the compiler support forNewtype
instances deriving) and purescript/purescript#3927 which suggests to export hidden newtype constructors when aCoercible
constraint fails to solve because of that.This also means that
Newtype
instances can only de declared for representationally equal types.I reckon that releasing this along with the next compiler release is perhaps too reckless but at least it should provide more context and motivation for the mentioned warnings.