confusing type error

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

confusing type error

Evan Laforge
I recently got a confusing error msg, and reduced it to a small case:

f1 :: Monad m => m Bool
f1 = f2 0 0 'a'

f2 :: Monad m => Int -> Float -> m Bool
f2 = undefined

From this, it's clear that f2 is being given an extra Char argument it
didn't ask for.  However, the error msg (ghc 7.8.3) is:

    Couldn't match type ‘m Bool’ with ‘Bool’
    Expected type: Char -> m Bool
      Actual type: Char -> Bool
    Relevant bindings include f1 :: m Bool (bound at Bug.hs:4:1)
    The function ‘f2’ is applied to three arguments,
    but its type ‘Int -> Float -> Char -> Bool’ has only three
    In the expression: f2 0 0 'a'
    In an equation for ‘f1’: f1 = f2 0 0 'a'

The confusing part is that 'f2' was applied to three arguments, but
it's type has only three.  It includes the Char in expected and actual
types, and implies that the type of 'f2' includes the Char.  So I took
quite a while to realize that the type of 'f2' in fact *didn't* expect
a Char (and had an 'm'), so that the "but its type" is *not* in fact
its declared type.

I suppose it infers a type for 'f2' based on its use, and that then
becomes the "actual" type, but it seems less confusing if it picked
the declared type of 'f2' as its actual type.  Perhaps this is working
as intended, but it it is confusing!  Especially the part about
"expected three but got three".

Ideally I'd like to see "too many arguments" or at least "expected
(Char -> m Bool) but actually 'm Bool'".  Actually I'd expect the
other way: "expected 'm Bool' but got (Char -> m Bool)' but I think
ghc has always done it backwards from how I expect.  It looks like
it's substituting (->) for 'm', so maybe it's one of those things
where ((->) a) is also a monad.
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

Richard Eisenberg-2
This seems straightforwardly to be a bug, to me. HEAD gives the same behavior you report below. Please post on the bug tracker at https://ghc.haskell.org/trac/ghc/newticket

Thanks!
Richard

On Dec 4, 2014, at 1:50 PM, Evan Laforge <[hidden email]> wrote:

> I recently got a confusing error msg, and reduced it to a small case:
>
> f1 :: Monad m => m Bool
> f1 = f2 0 0 'a'
>
> f2 :: Monad m => Int -> Float -> m Bool
> f2 = undefined
>
> From this, it's clear that f2 is being given an extra Char argument it
> didn't ask for.  However, the error msg (ghc 7.8.3) is:
>
>    Couldn't match type ‘m Bool’ with ‘Bool’
>    Expected type: Char -> m Bool
>      Actual type: Char -> Bool
>    Relevant bindings include f1 :: m Bool (bound at Bug.hs:4:1)
>    The function ‘f2’ is applied to three arguments,
>    but its type ‘Int -> Float -> Char -> Bool’ has only three
>    In the expression: f2 0 0 'a'
>    In an equation for ‘f1’: f1 = f2 0 0 'a'
>
> The confusing part is that 'f2' was applied to three arguments, but
> it's type has only three.  It includes the Char in expected and actual
> types, and implies that the type of 'f2' includes the Char.  So I took
> quite a while to realize that the type of 'f2' in fact *didn't* expect
> a Char (and had an 'm'), so that the "but its type" is *not* in fact
> its declared type.
>
> I suppose it infers a type for 'f2' based on its use, and that then
> becomes the "actual" type, but it seems less confusing if it picked
> the declared type of 'f2' as its actual type.  Perhaps this is working
> as intended, but it it is confusing!  Especially the part about
> "expected three but got three".
>
> Ideally I'd like to see "too many arguments" or at least "expected
> (Char -> m Bool) but actually 'm Bool'".  Actually I'd expect the
> other way: "expected 'm Bool' but got (Char -> m Bool)' but I think
> ghc has always done it backwards from how I expect.  It looks like
> it's substituting (->) for 'm', so maybe it's one of those things
> where ((->) a) is also a monad.
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

Brent Yorgey
In reply to this post by Evan Laforge
Int -> Float -> Char -> Bool  *is* in fact a valid type for f2, since ((->) Char) is a Monad. However, I agree the error message is confusing, especially the "expected n, but got n" part.

-Brent

On Thu, Dec 4, 2014 at 1:50 PM, Evan Laforge <[hidden email]> wrote:
I recently got a confusing error msg, and reduced it to a small case:

f1 :: Monad m => m Bool
f1 = f2 0 0 'a'

f2 :: Monad m => Int -> Float -> m Bool
f2 = undefined

From this, it's clear that f2 is being given an extra Char argument it
didn't ask for.  However, the error msg (ghc 7.8.3) is:

    Couldn't match type ‘m Bool’ with ‘Bool’
    Expected type: Char -> m Bool
      Actual type: Char -> Bool
    Relevant bindings include f1 :: m Bool (bound at Bug.hs:4:1)
    The function ‘f2’ is applied to three arguments,
    but its type ‘Int -> Float -> Char -> Bool’ has only three
    In the expression: f2 0 0 'a'
    In an equation for ‘f1’: f1 = f2 0 0 'a'

The confusing part is that 'f2' was applied to three arguments, but
it's type has only three.  It includes the Char in expected and actual
types, and implies that the type of 'f2' includes the Char.  So I took
quite a while to realize that the type of 'f2' in fact *didn't* expect
a Char (and had an 'm'), so that the "but its type" is *not* in fact
its declared type.

I suppose it infers a type for 'f2' based on its use, and that then
becomes the "actual" type, but it seems less confusing if it picked
the declared type of 'f2' as its actual type.  Perhaps this is working
as intended, but it it is confusing!  Especially the part about
"expected three but got three".

Ideally I'd like to see "too many arguments" or at least "expected
(Char -> m Bool) but actually 'm Bool'".  Actually I'd expect the
other way: "expected 'm Bool' but got (Char -> m Bool)' but I think
ghc has always done it backwards from how I expect.  It looks like
it's substituting (->) for 'm', so maybe it's one of those things
where ((->) a) is also a monad.
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

migmit-2
In reply to this post by Evan Laforge
I don't see a bug here. f2 is perfectly OK, so, let's examine f1 more closely.

It tries to get `m Bool` by applying f1 to three arguments: 0, 0, and 'a'. Now, since `f2` has the type `Int -> Float -> n Bool`, where `n` is of kind `* -> *` (and an instance of `Monad` class, but it's not yet the time to look for instances), we have `f2 0 :: Float -> n Bool` and `f2 0 0 :: n Bool`. Since that is applied to 'a', Haskell deduces that the last type should be something like `Char -> Something` — or, equivalently, `(->) Char Something`. Therefore, it can see that `n` is in fact `(->) Char` and `Something` is `Bool`. Therefore, `f2 0 0 'a' :: Bool`. But it is expecting `m Bool`, not `Bool` — which is exactly what an error message says.

Отправлено с iPad

> 4 дек. 2014 г., в 21:50, Evan Laforge <[hidden email]> написал(а):
>
> I recently got a confusing error msg, and reduced it to a small case:
>
> f1 :: Monad m => m Bool
> f1 = f2 0 0 'a'
>
> f2 :: Monad m => Int -> Float -> m Bool
> f2 = undefined
>
> From this, it's clear that f2 is being given an extra Char argument it
> didn't ask for.  However, the error msg (ghc 7.8.3) is:
>
>    Couldn't match type ‘m Bool’ with ‘Bool’
>    Expected type: Char -> m Bool
>      Actual type: Char -> Bool
>    Relevant bindings include f1 :: m Bool (bound at Bug.hs:4:1)
>    The function ‘f2’ is applied to three arguments,
>    but its type ‘Int -> Float -> Char -> Bool’ has only three
>    In the expression: f2 0 0 'a'
>    In an equation for ‘f1’: f1 = f2 0 0 'a'
>
> The confusing part is that 'f2' was applied to three arguments, but
> it's type has only three.  It includes the Char in expected and actual
> types, and implies that the type of 'f2' includes the Char.  So I took
> quite a while to realize that the type of 'f2' in fact *didn't* expect
> a Char (and had an 'm'), so that the "but its type" is *not* in fact
> its declared type.
>
> I suppose it infers a type for 'f2' based on its use, and that then
> becomes the "actual" type, but it seems less confusing if it picked
> the declared type of 'f2' as its actual type.  Perhaps this is working
> as intended, but it it is confusing!  Especially the part about
> "expected three but got three".
>
> Ideally I'd like to see "too many arguments" or at least "expected
> (Char -> m Bool) but actually 'm Bool'".  Actually I'd expect the
> other way: "expected 'm Bool' but got (Char -> m Bool)' but I think
> ghc has always done it backwards from how I expect.  It looks like
> it's substituting (->) for 'm', so maybe it's one of those things
> where ((->) a) is also a monad.
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

Yuras Shumovich
In reply to this post by Richard Eisenberg-2
It seems to be an instance of
https://ghc.haskell.org/trac/ghc/ticket/7869

But it is fixed (both in HEAD and 7.8). Probably the fix is partial?

On Thu, 2014-12-04 at 14:53 -0500, Richard Eisenberg wrote:

> This seems straightforwardly to be a bug, to me. HEAD gives the same behavior you report below. Please post on the bug tracker at https://ghc.haskell.org/trac/ghc/newticket
>
> Thanks!
> Richard
>
> On Dec 4, 2014, at 1:50 PM, Evan Laforge <[hidden email]> wrote:
>
> > I recently got a confusing error msg, and reduced it to a small case:
> >
> > f1 :: Monad m => m Bool
> > f1 = f2 0 0 'a'
> >
> > f2 :: Monad m => Int -> Float -> m Bool
> > f2 = undefined
> >
> > From this, it's clear that f2 is being given an extra Char argument it
> > didn't ask for.  However, the error msg (ghc 7.8.3) is:
> >
> >    Couldn't match type ‘m Bool’ with ‘Bool’
> >    Expected type: Char -> m Bool
> >      Actual type: Char -> Bool
> >    Relevant bindings include f1 :: m Bool (bound at Bug.hs:4:1)
> >    The function ‘f2’ is applied to three arguments,
> >    but its type ‘Int -> Float -> Char -> Bool’ has only three
> >    In the expression: f2 0 0 'a'
> >    In an equation for ‘f1’: f1 = f2 0 0 'a'
> >
> > The confusing part is that 'f2' was applied to three arguments, but
> > it's type has only three.  It includes the Char in expected and actual
> > types, and implies that the type of 'f2' includes the Char.  So I took
> > quite a while to realize that the type of 'f2' in fact *didn't* expect
> > a Char (and had an 'm'), so that the "but its type" is *not* in fact
> > its declared type.
> >
> > I suppose it infers a type for 'f2' based on its use, and that then
> > becomes the "actual" type, but it seems less confusing if it picked
> > the declared type of 'f2' as its actual type.  Perhaps this is working
> > as intended, but it it is confusing!  Especially the part about
> > "expected three but got three".
> >
> > Ideally I'd like to see "too many arguments" or at least "expected
> > (Char -> m Bool) but actually 'm Bool'".  Actually I'd expect the
> > other way: "expected 'm Bool' but got (Char -> m Bool)' but I think
> > ghc has always done it backwards from how I expect.  It looks like
> > it's substituting (->) for 'm', so maybe it's one of those things
> > where ((->) a) is also a monad.
> > _______________________________________________
> > Glasgow-haskell-users mailing list
> > [hidden email]
> > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
> >
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

Evan Laforge
In reply to this post by migmit-2
On Thu, Dec 4, 2014 at 12:59 PM, migmit <[hidden email]> wrote:
> It tries to get `m Bool` by applying f1 to three arguments: 0, 0, and 'a'. Now, since `f2` has the type `Int -> Float -> n Bool`, where `n` is of kind `* -> *` (and an instance of `Monad` class, but it's not yet the time to look for instances), we have `f2 0 :: Float -> n Bool` and `f2 0 0 :: n Bool`. Since that is applied to 'a', Haskell deduces that the last type should be something like `Char -> Something` — or, equivalently, `(->) Char Something`. Therefore, it can see that `n` is in fact `(->) Char` and `Something` is `Bool`. Therefore, `f2 0 0 'a' :: Bool`. But it is expecting `m Bool`, not `Bool` — which is exactly what an error message says.

Right, that's what I suspected was happening.  The confusion arrises
because it guesses that 'm' should be (->), and that deduction then
leads to a dead-end.  But when it reports the problem, it uses its
guessed 'm', rather that backing up to the declared value.

But surely always backing up to the declared unspecialized value is no
good either, because then you get vague errors.  All the compiler
knows is that when it simplifies as far as it can, it winds up with a
/= b, it doesn't know that I would have been surprised by its path a
few steps back.

But arity errors are common, and intentionally instantiating a prefix
type constructor like 'm a' as (->) is probably much less common.  So
perhaps there could be a heuristic that treats (->) specially and
includes an extra clause in the error if it unified a type variable to
(->)?

I suspect the "expected n but got n" error is also due to the same
thing, it counts arrows on one side but inferred arrows on the other?
Or something?  In any case, it seems like the two sides are counting
inconsistently.
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

Richard Eisenberg-2
The reason I said "That's a bug!" so confidently is because of the "expected n but got n" part. Even if everything else is OK, we need to fix that one bit.

And I tend to agree about using heuristics to report better error messages in the presence of instantiating a type variable with (->). I've been caught and confused by that, too.

Richard

On Dec 4, 2014, at 4:23 PM, Evan Laforge <[hidden email]> wrote:

> On Thu, Dec 4, 2014 at 12:59 PM, migmit <[hidden email]> wrote:
>> It tries to get `m Bool` by applying f1 to three arguments: 0, 0, and 'a'. Now, since `f2` has the type `Int -> Float -> n Bool`, where `n` is of kind `* -> *` (and an instance of `Monad` class, but it's not yet the time to look for instances), we have `f2 0 :: Float -> n Bool` and `f2 0 0 :: n Bool`. Since that is applied to 'a', Haskell deduces that the last type should be something like `Char -> Something` — or, equivalently, `(->) Char Something`. Therefore, it can see that `n` is in fact `(->) Char` and `Something` is `Bool`. Therefore, `f2 0 0 'a' :: Bool`. But it is expecting `m Bool`, not `Bool` — which is exactly what an error message says.
>
> Right, that's what I suspected was happening.  The confusion arrises
> because it guesses that 'm' should be (->), and that deduction then
> leads to a dead-end.  But when it reports the problem, it uses its
> guessed 'm', rather that backing up to the declared value.
>
> But surely always backing up to the declared unspecialized value is no
> good either, because then you get vague errors.  All the compiler
> knows is that when it simplifies as far as it can, it winds up with a
> /= b, it doesn't know that I would have been surprised by its path a
> few steps back.
>
> But arity errors are common, and intentionally instantiating a prefix
> type constructor like 'm a' as (->) is probably much less common.  So
> perhaps there could be a heuristic that treats (->) specially and
> includes an extra clause in the error if it unified a type variable to
> (->)?
>
> I suspect the "expected n but got n" error is also due to the same
> thing, it counts arrows on one side but inferred arrows on the other?
> Or something?  In any case, it seems like the two sides are counting
> inconsistently.
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

Dr. ERDI Gergo

But it says `expected Char -> Bool, got Char -> m Bool', note the `m' type constructor in the second one. So it's not `n' vs. `n'.

On Dec 5, 2014 10:50 PM, "Richard Eisenberg" <[hidden email]> wrote:
The reason I said "That's a bug!" so confidently is because of the "expected n but got n" part. Even if everything else is OK, we need to fix that one bit.

And I tend to agree about using heuristics to report better error messages in the presence of instantiating a type variable with (->). I've been caught and confused by that, too.

Richard

On Dec 4, 2014, at 4:23 PM, Evan Laforge <[hidden email]> wrote:

> On Thu, Dec 4, 2014 at 12:59 PM, migmit <[hidden email]> wrote:
>> It tries to get `m Bool` by applying f1 to three arguments: 0, 0, and 'a'. Now, since `f2` has the type `Int -> Float -> n Bool`, where `n` is of kind `* -> *` (and an instance of `Monad` class, but it's not yet the time to look for instances), we have `f2 0 :: Float -> n Bool` and `f2 0 0 :: n Bool`. Since that is applied to 'a', Haskell deduces that the last type should be something like `Char -> Something` — or, equivalently, `(->) Char Something`. Therefore, it can see that `n` is in fact `(->) Char` and `Something` is `Bool`. Therefore, `f2 0 0 'a' :: Bool`. But it is expecting `m Bool`, not `Bool` — which is exactly what an error message says.
>
> Right, that's what I suspected was happening.  The confusion arrises
> because it guesses that 'm' should be (->), and that deduction then
> leads to a dead-end.  But when it reports the problem, it uses its
> guessed 'm', rather that backing up to the declared value.
>
> But surely always backing up to the declared unspecialized value is no
> good either, because then you get vague errors.  All the compiler
> knows is that when it simplifies as far as it can, it winds up with a
> /= b, it doesn't know that I would have been surprised by its path a
> few steps back.
>
> But arity errors are common, and intentionally instantiating a prefix
> type constructor like 'm a' as (->) is probably much less common.  So
> perhaps there could be a heuristic that treats (->) specially and
> includes an extra clause in the error if it unified a type variable to
> (->)?
>
> I suspect the "expected n but got n" error is also due to the same
> thing, it counts arrows on one side but inferred arrows on the other?
> Or something?  In any case, it seems like the two sides are counting
> inconsistently.
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

Brent Yorgey
I think Richard is referring to "The function ‘f2’ is applied to three arguments,
    but its type ‘Int -> Float -> Char -> Bool’ has only three".  Note "applied to three ... but ... only three".   Here n = three.

-Brent

On Fri, Dec 5, 2014 at 9:55 AM, Dr. ÉRDI Gergő <[hidden email]> wrote:

But it says `expected Char -> Bool, got Char -> m Bool', note the `m' type constructor in the second one. So it's not `n' vs. `n'.

On Dec 5, 2014 10:50 PM, "Richard Eisenberg" <[hidden email]> wrote:
The reason I said "That's a bug!" so confidently is because of the "expected n but got n" part. Even if everything else is OK, we need to fix that one bit.

And I tend to agree about using heuristics to report better error messages in the presence of instantiating a type variable with (->). I've been caught and confused by that, too.

Richard

On Dec 4, 2014, at 4:23 PM, Evan Laforge <[hidden email]> wrote:

> On Thu, Dec 4, 2014 at 12:59 PM, migmit <[hidden email]> wrote:
>> It tries to get `m Bool` by applying f1 to three arguments: 0, 0, and 'a'. Now, since `f2` has the type `Int -> Float -> n Bool`, where `n` is of kind `* -> *` (and an instance of `Monad` class, but it's not yet the time to look for instances), we have `f2 0 :: Float -> n Bool` and `f2 0 0 :: n Bool`. Since that is applied to 'a', Haskell deduces that the last type should be something like `Char -> Something` — or, equivalently, `(->) Char Something`. Therefore, it can see that `n` is in fact `(->) Char` and `Something` is `Bool`. Therefore, `f2 0 0 'a' :: Bool`. But it is expecting `m Bool`, not `Bool` — which is exactly what an error message says.
>
> Right, that's what I suspected was happening.  The confusion arrises
> because it guesses that 'm' should be (->), and that deduction then
> leads to a dead-end.  But when it reports the problem, it uses its
> guessed 'm', rather that backing up to the declared value.
>
> But surely always backing up to the declared unspecialized value is no
> good either, because then you get vague errors.  All the compiler
> knows is that when it simplifies as far as it can, it winds up with a
> /= b, it doesn't know that I would have been surprised by its path a
> few steps back.
>
> But arity errors are common, and intentionally instantiating a prefix
> type constructor like 'm a' as (->) is probably much less common.  So
> perhaps there could be a heuristic that treats (->) specially and
> includes an extra clause in the error if it unified a type variable to
> (->)?
>
> I suspect the "expected n but got n" error is also due to the same
> thing, it counts arrows on one side but inferred arrows on the other?
> Or something?  In any case, it seems like the two sides are counting
> inconsistently.
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: confusing type error

Evan Laforge
I was going to ask if I should go ahead and file a bug anyway, but I
just noticed commit 09b7943321f89b945d10f8a914f4c2cbf73dff91 seems to
fix it.

Many thanks to Yuras!

On Fri, Dec 5, 2014 at 7:50 AM, Brent Yorgey <[hidden email]> wrote:

> I think Richard is referring to "The function ‘f2’ is applied to three
> arguments,
>     but its type ‘Int -> Float -> Char -> Bool’ has only three".  Note
> "applied to three ... but ... only three".   Here n = three.
>
> -Brent
>
> On Fri, Dec 5, 2014 at 9:55 AM, Dr. ÉRDI Gergő <[hidden email]> wrote:
>>
>> But it says `expected Char -> Bool, got Char -> m Bool', note the `m' type
>> constructor in the second one. So it's not `n' vs. `n'.
>>
>> On Dec 5, 2014 10:50 PM, "Richard Eisenberg" <[hidden email]> wrote:
>>>
>>> The reason I said "That's a bug!" so confidently is because of the
>>> "expected n but got n" part. Even if everything else is OK, we need to fix
>>> that one bit.
>>>
>>> And I tend to agree about using heuristics to report better error
>>> messages in the presence of instantiating a type variable with (->). I've
>>> been caught and confused by that, too.
>>>
>>> Richard
>>>
>>> On Dec 4, 2014, at 4:23 PM, Evan Laforge <[hidden email]> wrote:
>>>
>>> > On Thu, Dec 4, 2014 at 12:59 PM, migmit <[hidden email]> wrote:
>>> >> It tries to get `m Bool` by applying f1 to three arguments: 0, 0, and
>>> >> 'a'. Now, since `f2` has the type `Int -> Float -> n Bool`, where `n` is of
>>> >> kind `* -> *` (and an instance of `Monad` class, but it's not yet the time
>>> >> to look for instances), we have `f2 0 :: Float -> n Bool` and `f2 0 0 :: n
>>> >> Bool`. Since that is applied to 'a', Haskell deduces that the last type
>>> >> should be something like `Char -> Something` — or, equivalently, `(->) Char
>>> >> Something`. Therefore, it can see that `n` is in fact `(->) Char` and
>>> >> `Something` is `Bool`. Therefore, `f2 0 0 'a' :: Bool`. But it is expecting
>>> >> `m Bool`, not `Bool` — which is exactly what an error message says.
>>> >
>>> > Right, that's what I suspected was happening.  The confusion arrises
>>> > because it guesses that 'm' should be (->), and that deduction then
>>> > leads to a dead-end.  But when it reports the problem, it uses its
>>> > guessed 'm', rather that backing up to the declared value.
>>> >
>>> > But surely always backing up to the declared unspecialized value is no
>>> > good either, because then you get vague errors.  All the compiler
>>> > knows is that when it simplifies as far as it can, it winds up with a
>>> > /= b, it doesn't know that I would have been surprised by its path a
>>> > few steps back.
>>> >
>>> > But arity errors are common, and intentionally instantiating a prefix
>>> > type constructor like 'm a' as (->) is probably much less common.  So
>>> > perhaps there could be a heuristic that treats (->) specially and
>>> > includes an extra clause in the error if it unified a type variable to
>>> > (->)?
>>> >
>>> > I suspect the "expected n but got n" error is also due to the same
>>> > thing, it counts arrows on one side but inferred arrows on the other?
>>> > Or something?  In any case, it seems like the two sides are counting
>>> > inconsistently.
>>> > _______________________________________________
>>> > Glasgow-haskell-users mailing list
>>> > [hidden email]
>>> > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>> >
>>>
>>> _______________________________________________
>>> Glasgow-haskell-users mailing list
>>> [hidden email]
>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>>
>> _______________________________________________
>> Glasgow-haskell-users mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users