2012-10-17 6 views
6

Ich bekomme diesen Fehler, wenn ich versuche, ein Objekt zu deserialisieren.Generische Serialisierung in Haskell

Amy64.hs: GetException "too few bytes\nFrom:\tdemandInput\n\n" 

Die Ausgabedatei erstellt wird, und sieht wie folgt aus:

00000000 1f 8b 08 00 00 00 00 00 04 03 63 60 00 03 56 a7 |..........c`..V.| 
00000010 d2 f4 e2 4a 00 be b2 38 41 0d 00 00 00   |...J...8A....| 

Ich vermute, ich bin der neue Generika Sachen falsch verwenden. Hier ist mein Code. Übrigens, wenn ich die Zeilen 9, 22 und 23 lösche, bekomme ich das gleiche Ergebnis. Und wenn ich das gzip/ungzip-Zeug entferne, bekomme ich das gleiche Ergebnis.

{-# LANGUAGE DeriveGeneriC#-} 

import Data.Conduit (runResourceT, ($$), (=$)) 
import Data.Conduit.Binary (sinkFile, sourceFile) 
import Data.Conduit.Cereal (sinkGet, sourcePut) 
import Data.Conduit.Zlib (gzip, ungzip) 
import qualified Data.Serialize as DS (Serialize, get, put) 
import GHC.Generics (Generic) 
import Data.Serialize.Derive (derivePut, deriveGet) -- line 9 

readBug :: FilePath -> IO (Either String Bug) 
readBug f = 
    runResourceT $ sourceFile f $$ ungzip =$ sinkGet (DS.get) 

writeBug :: FilePath -> Bug -> IO() 
writeBug f t = 
    runResourceT $ sourcePut (DS.put t) $$ gzip =$ sinkFile f 

data Bug = Bug String deriving (Show, Generic) 

instance DS.Serialize Bug where 
    put = derivePut -- line 22 
    get = deriveGet -- line 23 

main = do 
    let a = Bug "Bugsy" 
    writeBug "x.dat" a 
    (Right b) <- readBug "x.dat" :: IO (Either String Bug) 
    print b 

Antwort

2

Es stellte sich heraus, dass mein Fehler nichts mit Generics per se zu tun hatte. Eine fehlerhafte Signatur auf der readBug-Funktion führte dazu, dass es versuchte, eine Either String Bug statt nur eine Bug zu lesen.

{-# LANGUAGE DeriveGeneriC#-} 

import Data.Conduit (runResourceT, ($$), (=$)) 
import Data.Conduit.Binary (sinkFile, sourceFile) 
import Data.Conduit.Cereal (sinkGet, sourcePut) 
import Data.Conduit.Zlib (gzip, ungzip) 
import qualified Data.Serialize as DS (Serialize, get, put) 
import GHC.Generics (Generic) 
import Data.Serialize.Derive (derivePut, deriveGet) -- line 9 

readBug :: FilePath -> IO Bug 
readBug f = 
    runResourceT $ sourceFile f $$ ungzip =$ sinkGet DS.get 

writeBug :: FilePath -> Bug -> IO() 
writeBug f t = 
    runResourceT $ sourcePut (DS.put t) $$ gzip =$ sinkFile f 

data Bug = Bug String deriving (Show, Generic) 

instance DS.Serialize Bug where 
    put = derivePut -- line 22 
    get = deriveGet -- line 23 

main :: IO() 
main = do 
    let a = Bug "Bugsy" 
    writeBug "x.dat" a 
    b <- readBug "x.dat" :: IO Bug 
    print b