2012-10-17 5 views
6

Je reçois cette erreur lorsque j'essaie de désérialiser un objet.Sérialisation générique dans Haskell

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

Le fichier de sortie est créé, et ressemble à ceci:

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....| 

Je pense que je utilise les nouveaux génériques des choses de manière incorrecte. Voici mon code. En passant, si je supprime les lignes 9, 22 et 23, j'obtiens le même résultat. Et si j'enlève les trucs gzip/ungzip, j'obtiens le même résultat.

{-# 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 

Répondre

2

Il s'est avéré que mon erreur n'avait rien à voir avec les génériques en tant que tels. Une signature de type incorrect sur la fonction readBug l'obligeait à essayer de lire un Either String Bug au lieu d'un Bug.

{-# 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 
Questions connexes