2010-09-08 12 views
5

Blocco stradale continuo durante il tentativo di apprendimento di Haskell.Errore di compilazione GHC derivante dall'importazione di Control.Exception

sto seguendo il "Real World Haskell", e quando si tratta di ottenere uno dei loro esempi complessi al lavoro, ottengo il seguente errore

"tipo ambiguo variabile e' in the constraint: GHC.Exception.Exception e' derivanti da un uso del `manico' a FoldDir.hs: 88: 14-61 correzione probabile: aggiungere una firma tipo che consente di risolvere questi variabile di tipo (s)"

miei bit rilevanti di codice sono:

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

Come si elimina questo errore?

+0

Possibile duplicato: http://stackoverflow.com/questions/431527/ambiguous-type-variable-error-msg –

risposta

14

È necessario specificare un tipo per l'argomento della funzione gestore, in modo che sappia quali tipi di eccezioni gestire.

è possibile farlo nominando la funzione

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

oppure utilizzando l'estensione ScopedTypeVariables:

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

Ciò fornisce a entrambi una risposta e aiuta nei miei tentativi di apprendere e comprendere Haskell. –

1

Control.Exception espone un'interfaccia diversa in GHC 6.10 e versioni successive. Per una soluzione rapida, cambiare

import Control.Exception (bracket, handle) 

a

import Control.OldException (bracket, handle) 
1

Control.OldException è deprecato. Con eccezioni estendibili, è necessario specificare un tipo per l'eccezione, anche se non viene mai utilizzata. La mia versione di maybeIO è

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 ha bisogno l'esplicito forall per portare il tipo di variabile a nel campo di applicazione, e il compilatore di bandiera GHC -XExplicitForAll utilizzare la esplicita forall. Non si può dare un try un tipo allo scoperto senza ottenere l'errore "Non si può dare una firma di tipo per un valore importato." Se si tenta la dichiarazione del tipo altrove, ad es. sul risultato di try task, quindi GHC non può risolverlo. Quindi sì, questo è un po 'imbarazzante per noi sostenitori della digitazione, ma migliora.