2010-09-08 4 views
5

Weitere Hindernisse beim Versuch, Haskell zu lernen.GHC-Kompilierungsfehler beim Import von Control.Exception

Ich verfolge das „Real World Haskell“, und wenn es darum geht, einen ihrer komplexen Beispiele kommt zu arbeiten, ich erhalte die folgenden Fehler

„Mehrdeutige Typ Variable e' in the constraint: GHC.Exception.Exception e‘ entstehen von einer Verwendung von `Griff‘ bei FoldDir.hs: 88: 14-61 Wahrscheinliche fix: eine Art Signatur hinzufügen, die diese Art Variable (n)“

Meine relevanten Bits des Codes sind fixiert:

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

Wie kann ich diesen Fehler beseitigen?

+0

Mögliche Duplikate: http://stackoverflow.com/questions/431527/ambiguous-type-variable-error-msg –

Antwort

14

Sie müssen einen Typ für das Argument der Prozedur angeben, damit er weiß, welche Arten von Ausnahmen behandelt werden sollen.

können Sie entweder tun dies durch die Funktion

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

Benennung oder durch die ScopedTypeVariables Erweiterung mit:

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

Dies bietet mir beide eine Antwort und hilft bei meinen Versuchen, Haskell zu lernen und zu verstehen. –

1

Control.Exception macht eine andere Schnittstelle in GHC 6.10 und höher. Für eine schnelle Lösung, ändern

import Control.Exception (bracket, handle) 

zu

import Control.OldException (bracket, handle) 
1

Control.OldException veraltet. Bei erweiterbaren Ausnahmen muss ein Typ für die Ausnahme angegeben werden, auch wenn sie niemals verwendet wird. Meine Version von maybeIO ist

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 

One die explizite forall braucht die Variable vom Typ a in Rahmen zu bringen, und der GHC Compiler-Flag -XExplicitForAll die explizite forall zu verwenden. Man kann try keinen Typ im Freien geben, ohne den Fehler zu bekommen "Sie können eine Typ-Signatur für einen importierten Wert nicht geben." Wenn man die Typdeklaration woanders versucht, z.B. auf das Ergebnis von try task dann kann GHC es nicht aussortieren. Also ja, das ist ein bisschen peinlich für uns starke Schreib-Befürworter, aber es wird besser.

Verwandte Themen