2012-10-17 27 views
6

Tôi nhận được lỗi này khi tôi cố gắng deserialize một đối tượng.serialization chung trong Haskell

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

Các tập tin đầu ra được tạo ra, và trông như thế này:

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

tôi nghi ngờ Tôi đang sử dụng các công cụ Generics mới không chính xác. Đây là mã của tôi. Nhân tiện, nếu tôi xóa các dòng 9, 22 và 23, tôi sẽ nhận được kết quả tương tự. Và nếu tôi loại bỏ các công cụ gzip/ungzip, tôi nhận được kết quả tương tự.

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

Trả lời

2

Hóa ra sai lầm của tôi không liên quan gì đến Generics per se. Chữ ký loại không hợp lệ trên chức năng readBug đã khiến nó cố đọc một số Either String Bug thay vì chỉ là 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