[GHC] #13368: Derive superclasses automatically if possible

#13368: Derive superclasses automatically if possible -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: #10607 Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- So I don't forget, this is like #10607 along another axis. Instead of writing {{{#!hs newtype IO_ a = IO_ (IO a) deriving newtype (Functor, Applicative, Monad, MonadIO) }}} allow writing {{{#!hs newtype IO_ a = IO_ (IO a) deriving newtype MonadIO }}} with the same meaning, are there any technical restrictions to this? This gets annoying in large hierarchies where you need `Eq`, `Ord`, `Num`, `Fractional`, `Floating`, `Real` and `RealFrac` just to derive {{{#!hs newtype F32 = F32 Float deriving newtype RealFloat }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13368 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13368: Derive superclasses automatically if possible -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #10607 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): This proposal shares many similarities with the [https://ghc.haskell.org/trac/ghc/wiki/IntrinsicSuperclasses IntrinsicSuperclasses] and [https://ghc.haskell.org/trac/ghc/wiki/InstanceTemplates InstanceTemplates] proposals, so I'll link them here. However, this proposal shares many of their downsides, which I'll briefly expound upon here. First, there's the technical challenges to this proposal. Not all instances are made equal, and `deriving` exposes this in many ways. For instance, suppose you tried this under your proposal: {{{#!hs class Traversable f => Witherable f where ... newtype Wrapped f a = Wrap (f a) deriving newtype Witherable }}} This would attempt the following: * `deriving newtype instance Functor f => Functor (Wrapped f)` * `deriving newtype instance Foldable f => Foldable (Wrapped f)` * `deriving newtype instance Traversable f => Traversable (Wrapped f)` * `deriving newtype instance Witherable f => Witherable (Wrapped f)` But trying to derive `Traversable` that way will fail, as it is ill-roled! See #13153. So not only would this throw an error, but it would throw an error that talks about a completely different class than `Witherable`. Mysterious. What's more, there's quite a number of ambiguities you'd have to deal with. For instance, what happens under your proposal in this scenario? {{{#!hs class Show a => MyShow a where ... data Foo deriving newtype MyShow instance Show Foo }}} Since `Show` is a superclass of `MyShow`, you might expect the `deriving newtype MyShow` clause to derive `instance Show Foo` as well. But there's already an `instance Show Foo`! So we'd either have to error here, or come up with a scheme for defaulting to existing instances when scenarios like the above one crop up. You might respond: "But that's easy! Just use the existing `Show Foo` instance!" But it gets even hairier than that: {{{#!hs class Show a => MyShow1 a where ... class Show a => MyShow2 a where ... data Foo deriving newtype MyShow1 deriving anyclass MyShow2 }}} Now we must ask: which of the two deriving clauses will implicitly derive `Show` behind the scenes? The choice matters, because a `newtype`-derived `Show` instance will be completely different than an `anyclass`-derived one! If the answer to this question is "use the first deriving clause", then now the order in which you write `deriving` clauses matters, which is a property that Haskell has never had up to this point. Finally, there's one more objection I will make not on technical grounds, but on aesthetic ones. This proposal would lose the property that all instances are explicitly asked for by the user. I (personally) find the idea of instances being snuck in behind the scenes quite shady and hard to reason about, and in addition, we'd lose things like concrete source locations for every instance, the ability to annotate all instances with Haddocks, etc. So my opinion in that it's a huge amount of complexity for very little gain and many drawbacks. I like the idea of doing something like this in Template Haskell, so I'm glad that someone is pursuing this in #10607. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13368#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13368: Derive superclasses automatically if possible -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #10607 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Iceland_jack): I figured there would be difficulties (`newtypes` causing trouble again via roles etc.), thanks for taking the time to respond. I'll continue thinking about this. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13368#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13368: Derive superclasses automatically if possible -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: wontfix | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #10607 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by Iceland_jack): * status: new => closed * resolution: => wontfix -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13368#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13368: Derive superclasses automatically if possible -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: wontfix | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #10607 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by songzh): I added a module `Data.Derive.Superclass` in derive- package[http://hackage.haskell.org/package/derive-topdown-0.0.2.0 which partially solve this problem. {{{ #!div style="font-size: 80%" {{{#!haskell
newtype IO_ a = IO_ (IO a) strategy_deriving_superclasses newtype_ ''MonadIO ''IO_
You will get:
strategy_deriving_superclasses newtype_ ''MonadIO ''IO_ ======> deriving newtype instance MonadIO IO_ deriving newtype instance Monad IO_ deriving newtype instance Applicative IO_ deriving newtype instance Functor IO_
Appearently, Functor f => Applicative f => Monad f => MonadIO f
newtype F32 = F32 Float newtype_deriving_superclasses ''RealFloat ''F32
You will get:
newtype_deriving_superclasses ''RealFloat ''F32 ======> deriving newtype instance RealFloat F32 deriving newtype instance RealFrac F32 deriving newtype instance Real F32 deriving newtype instance Num F32 deriving newtype instance Ord F32 deriving newtype instance Eq F32 deriving newtype instance Fractional F32 deriving newtype instance Floating F32 }}} }}}
Please try the package, if there are problem with it, please contact with me. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13368#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC