2012-05-24 14 views
7

Ich brauche eine Karte, die beliebige Werte enthalten kann, solange ihre Typen von derselben Typklasse sind. Mein erster naiver Ansatz war so etwas wie diese:Heterogene Karte

type HMap = forall a . MyClass a => M.Map Int a 

, aber es scheint nicht zu funktionieren: der folgende Code einen Compiler-Fehler gibt:

testFunction :: (forall a . MyClass a => M.Map Int a) -> Int -> IO() 
testFunction m i = do 
    case M.lookup i m of 
     Nothing -> return() 
     Just v -> someActionFromMyClass v >> putStrLn "OK" 


Ambiguous type variable `a0' in the constraint: 
    (MyClass a0) arising from a use of `m' 
Probable fix: add a type signature that fixes these type variable(s) 
In the second argument of `M.lookup', namely `m' 
In the expression: (M.lookup i m) 
In a stmt of a 'do' block: 
    case (M.lookup i m) of { 
    Nothing -> return() 
    Just v -> someActionFromMyClass v >> putStrLn "OK" } 

Ich dachte, dass ich spezielle heterogene Sammlung benötigen, aber seltsam Ich konnte nichts in Google außer this finden, aber diese Bibliothek scheint irgendwie ungepflegt und alt. Wie kann man das richtig machen (hoffentlich ohne andere Bibliotheken, nur mit GHC-Erweiterungen)?

Antwort

9

Verwenden Sie einen geeigneten existentiellen Typ.

{-# LANGUAGE ExistentialQuantification #-} 

data Elem = forall e. C e => Elem e 

type HMap = Map Int Elem 
+0

Vielen Dank! Es ist eine Schande, dass ich es selbst nicht habe. Ich glaube, ich muss mehr schlafen als ich jetzt) –

Verwandte Themen