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
Much shorter instancing/generics-deriving syntax #3426
Comments
Relates to:
|
I worked on anonymous type instances and deriving clauses attached to data and newtypes declarations this week-end. With deriving via and a newtype with generic instances, this example could be written much more concisely: data SomethingA = Alice | Alfred | Alex
derive (Eq, Ord)
derive (Show, Bounded, Enum) via (N SomethingA)
derive instance Generic SomethingA _
data SomethingB = Bob | Bart
derive (Eq, Ord)
derive (Show, Bounded, Enum) via (N SomethingB)
derive instance Generic SomethingB _
data SomethingC = Carol | Candice
derive (Eq, Ord)
derive (Show, Bounded, Enum) via (N SomethingC)
derive instance Generic SomethingC _
data SomethingD = David | Donald
derive (Eq, Ord)
derive (Show, Bounded, Enum) via (N SomethingD)
derive instance Generic SomethingD _ I’ve encountered a wall though. Deriving instances for higher kinded types requires us to know the kind of the derived type class (or at least of its last argument) in order to saturate the type constructor appropriately in the desugared instance. For example the following declaration: newtype Identity a = Identity a
derive (Eq, Ord)
derive Functor must desugar to: newtype Identity a = Identity a
derive instance Eq a => Eq (Identity a)
derive instance Ord a => Ord (Identity a)
derive instance Functor Identity We have to saturate Is there a way to compute the kind of a type class argument before typechecking? Should we add another couple of desugaring and typechecking steps after the current typechecking step? Or perhaps we could defer the desugaring of the derived clauses and interleave it with typechecking? |
This is something I noted in the PolyKinds PR. Typeclass/deriving desugaring really needs to be part of typechecking. The compiler currently has to do duplicate work to check both the desugared synonyms (which can have incomplete kind information) and the original classes/instances. Typeclass desugaring also does synonym expansion, but this also needs kind information which doesn't exist at that point. |
I've opened #4086 to provide a place for discussing this further. |
The first point has been addressed by #4085. |
This Haskell code is quite readable:
The equivalent PureScript code is basically unreadable, not to mention painful to write:
On top of the horrendous code bloat, twenty-eight useless instance names.
A few ideas:
Instance names could be cut out. I know this has been brought up before and decided against, with FFI as the excuse, but it would be the simplest solution so I figure I might as well mention it. Personally, I can't imagine more than a tiny fraction of instances are written with the intention of calling them from JavaScript. Perhaps there could be some kind of manual syntax for those use cases, something like
foreign export eqFoo :: Eq Foo
or something? I don't really want to worry about writing code for JavaScript in PureScript any more than I want to worry about writing code for C in Haskell.Bounded could be derivable, along with Enum if the library is being used. This would at least cut down some of those lines.
Unsure of the specifics, but Generic might be allowed to define something along the lines of
that could then be used for
EDIT: I guess this is really about giving an "opt-in" version of default method implementations, where you have to specify that you're going to borrow the defaults, in case that's less of an ordeal to add. If default method implementations were added, that would be even better.
as an equivalent to
The text was updated successfully, but these errors were encountered: