2010-09-08 6 views
5

Continuación de obstáculos al intentar aprender Haskell.Error de compilación de GHC debido a la importación de Control.Exception

estoy siguiendo el "Real World Haskell" y cuando se trata de conseguir uno de sus ejemplos complejos de trabajar, obtengo el siguiente error

"tipo ambiguo variables e' in the constraint: GHC.Exception.Exception e' derivada de un uso de `mango' en FoldDir.hs: 88: 14-61 solución probable: añadir una firma tipo que fija estas variables tipo (s)"

Mis bits relevantes de código son:

import Control.Exception (bracket, handle) 
maybeIO :: IO a -> IO (Maybe a) 
maybeIO act = handle (\_ -> return Nothing) (Just `liftM` act) 

¿Cómo puedo erradicar este error?

+0

Posible duplicado: http://stackoverflow.com/questions/431527/ambiguous-type-variable-error-msg –

Respuesta

14

Debe especificar un tipo para el argumento de la función del manejador, para que sepa qué tipos de excepciones manejar.

Usted puede hacer esto al nombrar la función

import Control.Exception (handle, SomeException) 
maybeIO act = handle handler (Just `liftM` act) 
    where handler :: SomeException -> IO (Maybe a) 
      handler _ = return Nothing 

o utilizando la extensión ScopedTypeVariables:

{-# LANGUAGE ScopedTypeVariables #-} 
import Control.Exception (handle, SomeException) 
maybeIO act = handle (\(_ :: SomeException) -> return Nothing) (Just `liftM` act) 
+1

Esto me proporciona una respuesta y me ayuda en mis intentos por aprender y comprender a Haskell. –

1

Control.Exception muestra una interfaz diferente en GHC 6.10 y posteriores. Para una solución rápida, cambie

import Control.Exception (bracket, handle) 

a

import Control.OldException (bracket, handle) 
1

Control.OldException está en desuso. Con excepciones extensibles, se necesita especificar un tipo para la excepción, incluso si nunca se usa. Mi versión de maybeIO es

perhaps ∷ forall a. IO a → IO (Maybe a) 
perhaps task = do 
    result ← (try ∷ IO a → IO (Either IOException a)) task 
    return $ either (const Nothing) Just result 

Uno tiene la explícita forall para llevar el tipo de variable a en alcance, y la bandera compilador GHC -XExplicitForAll utilizar la explícita forall. No se puede dar try un tipo al descubierto sin obtener el error "No se puede dar una firma de tipo para un valor importado". Si se prueba la declaración de tipo en otro lugar, p. en el resultado de try task, entonces GHC no puede resolverlo. Así que sí, esto es un poco embarazoso para nosotros, los defensores de la escritura fuerte, pero se pone mejor.

Cuestiones relacionadas