> On Jan 9, 2017, at 1:57 PM, Gershom B <gersh...@gmail.com> wrote:
> 
> Richard — your idea is really interesting. How would the dreaded role 
> restriction have to be modified to detect and allow this sort of granularity?

It wouldn't. The role restriction is purely on a method-by-method basis. (Right 
now, the role restriction is not enforced at the class level -- you just get a 
type error on the method that GND produces. See below.) So this new feature 
wouldn't interact with roles directly, at all.

Also, looking back through these emails, I realize my "insight" was really just 
the logical conclusion of David's original suggestion. Not much of an insight 
really, just some concrete syntax.

Richard

Example of bad GND:

> class Functor m => M m where
>   join :: m (m a) -> m a
> 
> newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
> 
> instance Functor m => Functor (ReaderT r m) where
>   fmap f x = ReaderT $ \r -> fmap f (runReaderT x r)
> 
> instance M m => M (ReaderT r m) where
>   join x = ReaderT $ \r -> join (fmap (($ r) . runReaderT) (runReaderT x r))
> 
> newtype N m a = MkN (ReaderT Int m a)
>   deriving (Functor, M)
> 


This produces

>     • Couldn't match representation of type ‘m (N m a)’
>                                with that of ‘m (ReaderT Int m a)’
>         arising from the coercion of the method ‘join’
>           from type ‘forall a.
>                      ReaderT Int m (ReaderT Int m a) -> ReaderT Int m a’
>             to type ‘forall a. N m (N m a) -> N m a’
>       NB: We cannot know what roles the parameters to ‘m’ have;
>         we must assume that the role is nominal
>     • When deriving the instance for (M (N m))


in GHC 8.0.1.

> 
> —g
> 
> 
> On January 9, 2017 at 1:34:17 PM, Richard Eisenberg (r...@cs.brynmawr.edu) 
> wrote:
>> I agree with David that using explicit `coerce`s can be quite verbose and 
>> may need ScopedTypeVariables  
>> and InstanceSigs. But visible type application should always work, because 
>> class methods  
>> always have a fixed type argument order. Regardless, requiring users to do 
>> all this for  
>> GND on Monad would be frustrating.
>> 
>> Actually, I just had an insight about this: there is no reason to use one 
>> deriving strategy  
>> for all methods in an instance. I can think of 4 ways to fill in the 
>> implementation of a class  
>> method in an instance:
>> 
>> 1. Explicit, hand-written implementation
>> 2. Defaulting to the implementation written in the class (or `error 
>> "undefined method"`  
>> in the absence of a default. This is essentially the default default.)
>> 3. Stock implementation provided by GHC
>> 4. Coerce
>> 
>> Ways 2, 3, and 4 all have extra restrictions: Way 2 might have extra type 
>> constraints due  
>> to a `default` signature. Way 3 restricts the choice of class and type. Way 
>> 4 works only  
>> on newtypes and then imposes role restrictions on the method's type.
>> 
>> GHC provides a `deriving` mechanism so that you can request Way 2 
>> (`default`), 3 (`stock`),  
>> or 4 (`newtype`) to fill in every method in a class. But there's no need to 
>> provide this  
>> feature at such a course granularity. What about:
>> 
>>> newtype N a = MkN (Foo a)
>>> instance Blah a => C (N a) where
>>> meth1 = ...
>>> deriving default meth2 -- a bit silly really, as you can just leave meth2 
>>> out
>>> deriving stock meth3 -- also silly, as C isn't a stock class, but you get 
>>> the idea
>>> deriving newtype meth4
>> 
>> We could also imagine
>> 
>>> deriving newtype instance Blah a => Monad (N a) where
>>> deriving default join -- not so silly anymore!
>> 
>> This syntax allows a `where` clause on standalone deriving allowing you to 
>> override  
>> the overall `deriving` behavior on a per-method basis.
>> 
>> I actually quite like this extension...
>> 
>> Richard
>> 
>> 
>>> On Jan 8, 2017, at 11:54 PM, David Feuer wrote:
>>> 
>>> You *can* do this, but it's often not so concise. When the type constructor 
>>> has parameters,  
>> you need to pin them down using ScopedTypeVariables. So you end up needing 
>> to give a signature  
>> for the method type in order to bring into scope variables you then use in 
>> the argument  
>> to coerce. If you have
>>> 
>>> newtype Foo f a = Foo (Foo f a)
>>> 
>>> then you may need
>>> 
>>> instance Bar f => Bar (Foo f) where
>>> bah = coerce (bah @ f @ a)
>>> :: forall a . C a => ...
>>> 
>>> to pin down the C instance.
>>> 
>>> If you don't want to use explicit type application (e.g., you're using a 
>>> library that  
>> does not claim to have stable type argument order), things get even more 
>> verbose.
>>> 
>>> On Jan 8, 2017 11:32 PM, "Joachim Breitner" >  
>> wrote:
>>> Hi,
>>> 
>>> just responding to this one aspect:
>>> 
>>> Am Sonntag, den 08.01.2017, 21:16 -0500 schrieb David Feuer:
>>>> but using defaults for
>>>> the others would give poor implementations. To cover this case, I
>>>> think it would be nice to add per-method GND-deriving syntax. This
>>>> could look something like
>>>> 
>>>> instance C T where
>>>> deriving f
>>>> g = ....
>>> 
>>> Assuming
>>> newtype T = MkT S
>>> 
>>> You can achieve this using
>>> 
>>> instance C T where
>>> f = coerce (f @F)
>>> g = ....
>>> 
>>> (which is precisely what GND does), so I don’t think any new syntax is
>>> needed here.
>>> 
>>> Greetings,
>>> Joachim
>>> 
>>> --
>>> Joachim “nomeata” Breitner
>>> m...@joachim-breitner.de • https://www.joachim-breitner.de/  
>> 
>>> XMPP: nome...@joachim-breitner.de • OpenPGP-Key:  
>> 0xF0FBF51F
>>> Debian Developer: nome...@debian.org  
>>> _______________________________________________
>>> Glasgow-haskell-users mailing list
>>> Glasgow-haskell-users@haskell.org  
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users  
>> 
>>> 
>>> _______________________________________________
>>> Glasgow-haskell-users mailing list
>>> Glasgow-haskell-users@haskell.org
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users  
>> 
>> _______________________________________________
>> Glasgow-haskell-users mailing list
>> Glasgow-haskell-users@haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users

Reply via email to