2016-07-08 20 views
1

I Funktion schreiben wollen, die heterogene Liste der speicherbaren Objekte (verschiedene Typen) stoßen kannHaskell heterogene Liste der speicherbaren Objekte

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE RankNTypes, ExistentialQuantification, ImpredicativeTypes #-} 

pokeMany :: Ptr b -> Int -> [forall a. Storable a => a] -> IO() 
pokeMany _ _ [] = return() 
pokeMany ptr offset (x:xs) = do 
    pokeByteOff ptr offset x 
    pokeMany ptr (offset + sizeOf x) xs 

somePoke :: Ptr a -> Int -> Int -> IO() 
somePoke ptr x1 x2 = pokeMany ptr 0 [x1, x2] 

Aber ich bekomme Fehler kompilieren:

No instance for (Storable a1) arising from a use of `sizeOf' 
The type variable `a1' is ambiguous 
Note: there are several potential instances: 
    instance Storable CChar -- Defined in `Foreign.C.Types' 
    instance Storable CClock -- Defined in `Foreign.C.Types' 
    instance Storable CDouble -- Defined in `Foreign.C.Types' 

Couldn't match expected type `a2' with actual type `Int' 
    `a2' is a rigid type variable bound by 
     a type expected by the context: Storable a2 => a2 

und andere ..

.

Dann erstelle ich einige Datentyp

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE RankNTypes, ExistentialQuantification, ImpredicativeTypes #-} 

data AnyStorable = forall a. Storable a => AnyStorable a 

pokeMany :: Ptr b -> Int -> [AnyStorable] -> IO() 
pokeMany _ _ [] = return() 
pokeMany ptr offset (AnyStorable x:xs) = do 
    pokeByteOff ptr offset x 
    pokeMany ptr (offset + sizeOf x) xs 

somePoke :: Ptr a -> Int -> Int -> IO() 
somePoke ptr n c = pokeMany ptr 0 [AnyStorable n, AnyStorable c, AnyStorable 'a'] 

Der obige Code hat keine Kompilierungsfehler.

Kann ich pokeMany Funktion schreiben, ohne einen neuen Datentyp wie AnyStorable zu erstellen?

Antwort

1

Kurz gesagt, nein. Was Sie dafür benötigen, wäre exists Schlüsselwort, um die Signatur der Funktion anzugeben, die der Sammlung zugeordnet wird. Die Verwendung von im Datentyp drückt das Gleiche auf der anderen Seite aus.

BTW, könnten Sie in Betracht ziehen AnyStorable eine Instanz von Storable zu machen.

+0

Natürlich haben Sie Recht. 'AnyStorable' muss eine Instanz von' Storable' sein. – Bet