Jo0o0
Jo0o0

Reputation: 531

arising from a use of `Control.Exception.catch'

When i load a haskell file, it has error

module REPL(REPL(..), repl) where
import qualified Control.Exception as E
import System.Console.Readline(readline, addHistory)

data REPL s = REPL {
    repl_init :: IO (String, s),        -- prompt and initial state
    repl_eval :: s -> String -> IO (Bool, s),       -- quit flag and new state
    repl_exit :: s -> IO ()
    }

repl :: REPL s -> IO ()
repl p = do
    (prompt, state) <- repl_init p
    let loop s = (do
        mline <- readline prompt
        case mline of
        Nothing -> loop s
        Just line -> do
            (quit, s') <- repl_eval p s line
            if quit then
            repl_exit p s'
             else do
            addHistory line
            loop s'
        ) E.catch undefined (\(e :: E.SomeException) -> putStrLn "Handled exception!"
        )
    loop state

REPL.hs:21:5:
    Couldn't match expected type `IO (Maybe String)'
           against inferred type `t -> Maybe String'
    In a stmt of a 'do' expression: mline <- readline prompt
    In the expression:
        (do { mline <- readline prompt;
              case mline of {
                Nothing -> loop s
                Just line
                  -> do { (quit, s') <- repl_eval p s line;
                          .... } } })
          E.catch
          undefined
          (\ (e :: E.SomeException) -> putStrLn "Handled exception!")
    In the definition of `loop':
        loop s = (do { mline <- readline prompt;
                       case mline of {
                         Nothing -> loop s
                         Just line -> do { ... } } })
                   E.catch
                   undefined
                   (\ (e :: E.SomeException) -> putStrLn "Handled exception!")

Upvotes: 2

Views: 1495

Answers (2)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

Use scoped type variables by including this line at the top of your file:

{-# LANGUAGE ScopedTypeVariables #-}

Or in a GHCi session just do:

> :set -XScopedTypeVariables

And in your catch function provide a signature. In GHCi:

> import Control.Exception as E
> E.catch undefined (\(e :: E.SomeException) -> putStrLn "Handled exception!")
Handled exception!

Celebrate good times, come on!

Upvotes: 10

ntc2
ntc2

Reputation: 11922

It would help to see the actual code that's giving you trouble, but please see the below for an example of the problem you describe and solution to the example by adding a type signature. In ghci:

> :m + Control.Exception
> print "hello world" `Control.Exception.catch` (\_ -> print "goodby world")

<interactive>:1:21:
    Ambiguous type variable `e' in the constraint:
      (Exception e) arising from a use of `Control.Exception.catch'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression:
        print "hello world"
      `Control.Exception.catch`
        (\ _ -> print "goodby world")
    In an equation for `it':
        it
          = print "hello world"
          `Control.Exception.catch`
            (\ _ -> print "goodby world")
> print "hello world" `Control.Exception.catch` ((\_ -> print "goodby world") :: IOException -> IO ())
"hello world"

The point is that the catch expression (\_ -> print "goodby world") doesn't constrain the type of its argument. I expect you're have a similar problem.

Upvotes: 2

Related Questions