I think we're basically in agreement. I'm more than happy to write those 5-6 instances that legitimately aren't safe to derive.
-Edward > On Oct 16, 2013, at 1:30 PM, Richard Eisenberg <e...@cis.upenn.edu> wrote: > > It seems like we may be on the same page now. Do you agree with my previous > email that the change to the GND check will not solve *all* your problems? > That is, there will be some derived instances you will have to hand-write, > but (I think) for good reason. > > Richard > >> On Oct 16, 2013, at 12:46 PM, Edward Kmett wrote: >> >> >> >>> On Oct 16, 2013, at 9:28 AM, Simon Peyton-Jones <simo...@microsoft.com> >>> wrote: >>> >>> I think I know what to do about the GND + roles question. >>> >>> First, the problem. Here’s an example: >>> class Trans t a where >>> foo :: t a -> t a >>> >>> newtype N x = MkN x deriving( Trans Maybe ) >>> >>> As things stand, Trans gets roles (representational, nominal). The second >>> parameter ‘a’ gets a nominal role because we don’t know what ‘t’ will get >>> instantiated too. >>> >>> As a result the attempted GND is rejected because of the new role stuff. >>> But with 7.6.3 we’ll get an instance >>> instance Trans Maybe a => Trans Maybe (N a) >>> from the GND mechanism. >>> >>> Do I have this right? >>> >>> >>> Second, there is a Good Reason for the problem. Suppose I said >>> newtype N x = MkN x deriving( Trans D ) >>> where D was a data family. Then the foo method for (D x) might seg-fault >>> if applied to a (D (N x)) value. So the current GND is treading on very >>> thin ice, and it is ice that the author (Edward) does not control. His >>> clients control it. >>> >>> Do I have this right? >>> >>> >>> Third, there is an easy solution. As Richard observed in a separate thread >>> about Coercible, GND does not attempt to build a coercion to witness >>> Trans Maybe x ~R Trans Maybe (N x) >>> >>> Rather, it builds a dictionary for (Trans Maybe (N x)) thus >>> dTransMaybeN :: Trans Maybe x -> Trans Maybe (N x) >>> dTransMaybeN d = MkTrans (sel_foo d |> co) >>> >>> where the (sel_foo d) selects the foo method from d. That is, we actually >>> cast the methods, not the dictionary as a whole. So what we need is a >>> coercion between >>> Maybe x ~R Maybe (N x) >>> Can we get that? Yes of course! Maybe has a representational role. >>> >>> Bottom line: we should accept or reject a GND attempt not on the basis of >>> the role of the class, but rather on whether the method types are >>> coercible. Indeed, this is just what we agreed some days ago >>> http://www.haskell.org/pipermail/glasgow-haskell-users/2013-October/024386.html >>> >>> So I think this solves Edward’s problem below. >>> >>> >>> Moreover, I think this solves the other failures in >>> http://www.haskell.org/pipermail/ghc-devs/2013-October/002961.html. Here >>> is one example, in that email. smallcheck has this: >>> newtype Series m a = Series (ReaderT Depth (LogicT m) a) >>> deriving >>> ( …, MonadLogic) >>> >>> where logict defines MonadLogic thus: >>> >>> class (MonadPlus m) => MonadLogic m where >>> msplit :: m a -> m (Maybe (a, m a)) >>> >>> So the “bottom line” check above will attempt to find a cocercion betwem >>> msplit’s type with m=Series m, and with m=ReaderT Depth (LogitT m). Right? >>> So on the left of msplit’s arrow, we’ll ask can we prove >>> >>> Series m a ~R ReaderT Depth (LogicT m) a >>> >>> Can we show that? Yes, of course… that is the very newtype coercion for >>> Series. >>> >>> In short, I think we are fine, once Richard has implemented the new GND >>> test. >>> >>> Am I wrong? >> >> I have no counter examples for GND based on coercing dictionaries rather >> than parameters at this time and I do agree that this does strike me as >> sufficient to plug the obvious holes in the current approach. >> >> I'll keep looking and see if I can't find a way to subvert the system, but >> this sounds promising for roles. >> >> In light of this, the NPR approach that Richard suggested strikes me as more >> relevant to fixing up Coercible than GND and as you mentioned we can very >> well spend another release cycle to get Coercible right. >> >> Assuming the dictionary casts work the way we expect, I'm think I'm sold. >> The main thing I don't want to do is wake up after 7.8 is cut and personally >> have to write 4000 lines of previously derived instances that are provably >> safe, because of an overly restrictive role scheme. I'm cautiously >> optimistic that this will be sufficient to keep me out of that scenario. ;) >> >> -Edward >> >>> Simon >>> >>> >>> From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Edward >>> Kmett >>> Sent: 13 October 2013 23:02 >>> To: ghc-devs; Richard Eisenberg >>> Subject: Re: More GND + role inference woes >>> >>> I didn't think I was using GND much at all, but apparently I was wrong. >>> >>> >>> >>> After Ben's initial foray into building linear, I went and looked at the >>> other applications of GeneralizedNewtypeDeriving in my code and found that >>> in parsers, all of the derived instances for the supplied parser >>> transformers fail. >>> >>> >>> >>> This also affects any attempt to use GND to do deriving for any monad >>> transformer stack that isn't fully instantiated to concrete terms. This is >>> actually a very common idiom to avoid writing boilerplate on top of >>> transformers: >>> >>> >>> >>> newtype T m a = T { runT : StateT MyState (ReaderT MyEnv) m a } >>> >>> deriving (Functor, Monad, Applicative, MonadState MyState, MonadReader >>> MyEnv, ...) >>> >>> >>> >>> As I rummage through more of my code, I actually can't find any instances >>> of GND that do still work that aren't of the form: >>> >>> >>> >>> newtype Foo a = Foo { runFoo :: a } deriving ... >>> >>> >>> >>> Literally every other example I have of GND in the code I maintain has >>> something in it that causes it to run afoul of the new roles machinery. >>> >>> >>> >>> I'd say the problem is more widespread than we thought. >>> >>> >>> >>> -Edward >>> >>> >>> >>> On Sun, Oct 13, 2013 at 5:26 PM, Edward Kmett <ekm...@gmail.com> wrote: >>> >>> Ben Gamari was trying to update my linear package to work with GHC HEAD. >>> >>> >>> >>> Along the way he noted an example of the new GND+role inference machinery >>> failing rather spectacularly. >>> >>> >>> >>> http://hackage.haskell.org/package/linear-1.3/docs/src/Linear-Affine.html#Point >>> >>> >>> >>> Note the number of classes that the current proposal would force us to hand >>> implement. >>> >>> >>> >>> =( >>> >>> >>> >>> -Edward >>> >
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs