No instance - but it could just put one in the context

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

No instance - but it could just put one in the context

Tom Ellis
I'm puzzled by GHC's behaviour in the following program.

'baz = bar . foo' does not work because there is "no instance for ...".  But
if I manually assume those instances in the context all is fine.  Why can
GHC not infer that context?  Is there any extension or clever trick I can
use to get this to infer like I want?

Thanks,

Tom



{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}

class Foo a b
class Bar a b
type family Quux a

foo :: ( Foo a b
       , b ~ Quux a )
    => a
    -> Quux a
foo = undefined

bar :: Bar a b
    => a
    -> b
bar = undefined

-- Doesn't work
-- No instance for (Bar (Quux a0) c0) arising from a use of ‘bar’
-- No instance for (Foo a0 (Quux a0)) arising from a use of ‘foo’
--baz = bar . foo

baz' :: ( Foo a (Quux a)
        , Bar (Quux a) b )
     => a
     -> b
baz' = bar . foo
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: No instance - but it could just put one in the context

Adam Bergmark-2
This works if you enable NoMonomorphismRestriction.

Cheers,
Adam


On Thu, 22 Feb 2018 at 23:41 Tom Ellis <[hidden email]> wrote:
I'm puzzled by GHC's behaviour in the following program.

'baz = bar . foo' does not work because there is "no instance for ...".  But
if I manually assume those instances in the context all is fine.  Why can
GHC not infer that context?  Is there any extension or clever trick I can
use to get this to infer like I want?

Thanks,

Tom



{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}

class Foo a b
class Bar a b
type family Quux a

foo :: ( Foo a b
       , b ~ Quux a )
    => a
    -> Quux a
foo = undefined

bar :: Bar a b
    => a
    -> b
bar = undefined

-- Doesn't work
-- No instance for (Bar (Quux a0) c0) arising from a use of ‘bar’
-- No instance for (Foo a0 (Quux a0)) arising from a use of ‘foo’
--baz = bar . foo

baz' :: ( Foo a (Quux a)
        , Bar (Quux a) b )
     => a
     -> b
baz' = bar . foo
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: No instance - but it could just put one in the context

Tom Ellis
That's amazing!  How many times have I been tripped up by that ...  Thanks a
lot, Adam.

On Thu, Feb 22, 2018 at 11:11:18PM +0000, Adam Bergmark wrote:

> This works if you enable NoMonomorphismRestriction.
>
> On Thu, 22 Feb 2018 at 23:41 Tom Ellis <
> [hidden email]> wrote:
>
> > I'm puzzled by GHC's behaviour in the following program.
> >
> > 'baz = bar . foo' does not work because there is "no instance for ...".
> > But
> > if I manually assume those instances in the context all is fine.  Why can
> > GHC not infer that context?  Is there any extension or clever trick I can
> > use to get this to infer like I want?
> >
> > Thanks,
> >
> > Tom
> >
> >
> >
> > {-# LANGUAGE MultiParamTypeClasses #-}
> > {-# LANGUAGE TypeFamilies #-}
> > {-# LANGUAGE FlexibleContexts #-}
> >
> > class Foo a b
> > class Bar a b
> > type family Quux a
> >
> > foo :: ( Foo a b
> >        , b ~ Quux a )
> >     => a
> >     -> Quux a
> > foo = undefined
> >
> > bar :: Bar a b
> >     => a
> >     -> b
> > bar = undefined
> >
> > -- Doesn't work
> > -- No instance for (Bar (Quux a0) c0) arising from a use of ‘bar’
> > -- No instance for (Foo a0 (Quux a0)) arising from a use of ‘foo’
> > --baz = bar . foo
> >
> > baz' :: ( Foo a (Quux a)
> >         , Bar (Quux a) b )
> >      => a
> >      -> b
> > baz' = bar . foo
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: No instance - but it could just put one in the context

Tom Ellis
My next question is, could GHC suggest NoMonomorphismRestriction when it
comes across such code?

(In the same way it suggests FlexibleContexts, etc.)

On Thu, Feb 22, 2018 at 11:16:35PM +0000, Tom Ellis wrote:

> That's amazing!  How many times have I been tripped up by that ...  Thanks a
> lot, Adam.
>
> On Thu, Feb 22, 2018 at 11:11:18PM +0000, Adam Bergmark wrote:
> > This works if you enable NoMonomorphismRestriction.
> >
> > On Thu, 22 Feb 2018 at 23:41 Tom Ellis <
> > [hidden email]> wrote:
> >
> > > I'm puzzled by GHC's behaviour in the following program.
> > >
> > > 'baz = bar . foo' does not work because there is "no instance for ...".
> > > But
> > > if I manually assume those instances in the context all is fine.  Why can
> > > GHC not infer that context?  Is there any extension or clever trick I can
> > > use to get this to infer like I want?
> > >
> > > Thanks,
> > >
> > > Tom
> > >
> > >
> > >
> > > {-# LANGUAGE MultiParamTypeClasses #-}
> > > {-# LANGUAGE TypeFamilies #-}
> > > {-# LANGUAGE FlexibleContexts #-}
> > >
> > > class Foo a b
> > > class Bar a b
> > > type family Quux a
> > >
> > > foo :: ( Foo a b
> > >        , b ~ Quux a )
> > >     => a
> > >     -> Quux a
> > > foo = undefined
> > >
> > > bar :: Bar a b
> > >     => a
> > >     -> b
> > > bar = undefined
> > >
> > > -- Doesn't work
> > > -- No instance for (Bar (Quux a0) c0) arising from a use of ‘bar’
> > > -- No instance for (Foo a0 (Quux a0)) arising from a use of ‘foo’
> > > --baz = bar . foo
> > >
> > > baz' :: ( Foo a (Quux a)
> > >         , Bar (Quux a) b )
> > >      => a
> > >      -> b
> > > baz' = bar . foo
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: No instance - but it could just put one in the context

Tom Ellis
Oh, it does already seem to mention this, which is great!

On Thu, Feb 22, 2018 at 11:25:29PM +0000, Tom Ellis wrote:

> My next question is, could GHC suggest NoMonomorphismRestriction when it
> comes across such code?
>
> (In the same way it suggests FlexibleContexts, etc.)
>
> On Thu, Feb 22, 2018 at 11:16:35PM +0000, Tom Ellis wrote:
> > That's amazing!  How many times have I been tripped up by that ...  Thanks a
> > lot, Adam.
> >
> > On Thu, Feb 22, 2018 at 11:11:18PM +0000, Adam Bergmark wrote:
> > > This works if you enable NoMonomorphismRestriction.
> > >
> > > On Thu, 22 Feb 2018 at 23:41 Tom Ellis <
> > > [hidden email]> wrote:
> > >
> > > > I'm puzzled by GHC's behaviour in the following program.
> > > >
> > > > 'baz = bar . foo' does not work because there is "no instance for ...".
> > > > But
> > > > if I manually assume those instances in the context all is fine.  Why can
> > > > GHC not infer that context?  Is there any extension or clever trick I can
> > > > use to get this to infer like I want?
> > > >
> > > > Thanks,
> > > >
> > > > Tom
> > > >
> > > >
> > > >
> > > > {-# LANGUAGE MultiParamTypeClasses #-}
> > > > {-# LANGUAGE TypeFamilies #-}
> > > > {-# LANGUAGE FlexibleContexts #-}
> > > >
> > > > class Foo a b
> > > > class Bar a b
> > > > type family Quux a
> > > >
> > > > foo :: ( Foo a b
> > > >        , b ~ Quux a )
> > > >     => a
> > > >     -> Quux a
> > > > foo = undefined
> > > >
> > > > bar :: Bar a b
> > > >     => a
> > > >     -> b
> > > > bar = undefined
> > > >
> > > > -- Doesn't work
> > > > -- No instance for (Bar (Quux a0) c0) arising from a use of ‘bar’
> > > > -- No instance for (Foo a0 (Quux a0)) arising from a use of ‘foo’
> > > > --baz = bar . foo
> > > >
> > > > baz' :: ( Foo a (Quux a)
> > > >         , Bar (Quux a) b )
> > > >      => a
> > > >      -> b
> > > > baz' = bar . foo
> > _______________________________________________
> > Haskell-Cafe mailing list
> > To (un)subscribe, modify options or view archives go to:
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > Only members subscribed via the mailman list are allowed to post.
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.