Hello,

I hope that this isn't again something which has been fixed recently,
I am looking at version 6.6. (is there a newer one in Debian?)

I am making an observation about error messages.

For example, I recently fixed a bug by changing a line:

    (xR, _) <- _withInitRSV Nothing (const ()) xRP

to read:

    (xR, _) <- _withInitRSV Nothing (const $ return ()) xRP

The error message from the compiler was:

Stream.hs:106:37:
    Couldn't match expected type `IO t' against inferred type `()'
    In the second argument of `_withInitRSV', namely `(const ())'
    In a 'do' expression:
        (xR, _) <- _withInitRSV Nothing (const ()) xRP
    In the expression:
        do RSVWriter c xRP <- takeMVar wm
           wsFinish c
           free c
           (xR, _) <- _withInitRSV Nothing (const ()) xRP
           return xR

I am assuming that the "expected type" is the type inferred for the
context in which the expression occurs, and the "inferred type" is the
type inferred for the expression from the already-accepted judgments
of other contexts.

The thing which is confusing to me is that the expression which the
error message refers to, "(const ())", doesn't have either the type
named in the expected type, or the inferred type. Rather the context
of that expression expects:

something -> IO b

while the type inferred from other contexts (e.g. definitions of
"const" and "()") for that expression is:

anything -> ()

Presumably the compiler unifies 'something' with 'anything', proceeds,
gets stuck on unifying 'IO b' with '()', and spits out the error
message for these subnodes. If I had made a more serious mistake, for
instance by changing the line to:

    (xR, _) <- _withInitRSV Nothing () xRP

then the error message would be more informative:

Stream.hs:106:37:
    Couldn't match expected type `Ptr (RSV e i) -> IO t'
           against inferred type `()'
    In the second argument of `_withInitRSV', namely `()'
    In a 'do' expression: (xR, _) <- _withInitRSV Nothing (()) xRP
    In the expression:
        do RSVWriter c xRP <- takeMVar wm
           wsFinish c
           free c
           (xR, _) <- _withInitRSV Nothing () xRP
           return xR

In this case, the given expression "()" actually has the two
alternative typings which are displayed in the message, presumably
because here the type incompatibility was at the top node of the type. 
I think this makes fixing the error much easier, since one doesn't
have to guess what the relationship between the expression and the two
given types is.

I should think that it would be useful if, every time the compiler
gave an expression and two alternative typings, those typings were
typings of the given expression. Would this be too difficult to
implement for the case of the first example, where it was possible to
partially unify the function types? Or is there some other reason to
avoid making such a change to the compiler?

Many thanks,

Frederik Eaton

-- 
http://ofb.net/~frederik/
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to