tags:

views:

1174

answers:

4

I don't think it is a bug, but I am a bit puzzled as to why that doesn't work. A bonus question is why does it mention variable e? There is no variable e.

    Prelude> :m +Control.Exception
    Prelude Control.Exception> handle (\_-> return "err") undefined

    <interactive>:1:0:
        Ambiguous type variable `e' in the constraint:
          `Exception e'
            arising from a use of `handle' at <interactive>:1:0-35
        Probable fix: add a type signature that fixes these type variable(s)
    Prelude Control.Exception> 

Apparently it works fine in ghci 6.8, I am using 6.10.1.

Edit: I have minimized the code. I expect that to have the same result in both 6.8 and 6.10

class C a                                                                                                     

foo :: C a => (a -> Int)-> Int                                                                                
foo _ = 1                                                                                                     

arg :: C a => a -> Int                                                                                        
arg _ = 2                                                                                                     

bar :: Int                                                                                                    
bar = foo arg

trying to compile it:

[1 of 1] Compiling Main             ( /tmp/foo.hs, interpreted )

/tmp/foo.hs:12:10:
    Ambiguous type variable `a' in the constraint:
      `C a' arising from a use of `arg' at /tmp/foo.hs:12:10-12
    Probable fix: add a type signature that fixes these type variable(s)
Failed, modules loaded: none.
Prelude Control.Exception> 
+4  A: 

This problem shows up only in GHC 6.10; it can't be duplicated in GHC 6.8 because the type of handle is different:

: nr@homedog 620 ; ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
Loading package base ... linking ... done.
Prelude> :m +Control.Exception
Prelude Control.Exception>  handle (\_ -> return "err") undefined
"err"
Prelude Control.Exception>


OK maybe I can get this right at last. I think the problem is not the monomorphism restriction, but rather you've hit an instance of the Read/Show problem: you're offering to handle some type of exception, in the new version of `handle, there is more than one type of exception, and the type of that exception does not appear in your result. So the compiler has no way of knowing which type of exception you're trying to handle. One way to work this is to pick one. Here's some code that works:

Prelude Control.Exception> let alwaysError :: SomeException -> IO String; alwaysError = \_ -> return "err"
Prelude Control.Exception> handle alwaysError undefined
"err"

Incidentally, the example use of handle in the GHC library documentation does not compile under 6.10. I have filed a bug report.

Norman Ramsey
Why does the compiler need to know which exception? The function handles every type from the class.
luntain
Because of the type of `handle`; any use of `handle` must be applied to *one* particular type from the Exception class. Since your handler works for all types in the class, there's no way for the compiler to assign a type to `handle`. (The `e` comes from the type of `handle`.)
Norman Ramsey
If you use the ScopedTypeVariables extension you can just do 'handle (\(_ :: SomeException) -> return "err") undefined'.
Porges
A: 

"Exception e" is likely from the type signature of "handle".

The documentation says:

handle :: Exception e => (e -> IO a) -> IO a -> IO a

In GHC 6.8 it used to be different, which would explain why I don't get that error.

handle :: (Exception -> IO a) -> IO a -> IO a

Seems you're running into the monomorphism restriction. That "_"-Pattern must be monomorphic (which it is with ghc 6.8) or explicitly typed. A "workaround" is to put the pattern on the left hand side of a definition, where it constitutes a "simple pattern binding" as specified by the Haskell Report.

Try this:

let f _ = return "err"
handle f undefined

http://www.haskell.org/haskellwiki/Monomorphism_restriction

Waquo
let f _ = return "err"handle f undefinedgives the same error
luntain
How about the pragma{-# -XNoMonomorphismRestriction #-}
Waquo
I think it's {-# LANGUAGE NoMonomorphismRestriction #-}
Waquo
the pragma doesn't help
luntain
A: 

A workaround is to use Control.OldException in ghc 6.10.* instead of Control.Exception.

Thomas
A: 

Try giving your handler the type SomeException -> IO x, where x is a concrete type, e.g.

import Control.Exception
let f _ = putStrLn "error" :: SomeException -> IO () 
in handle f undefined