2011-04-13 106 views
2

我有一个newtype我想保存在文件中,这样的事情:数据类型,以字节串

type Index = (Int, Int) 

newtype Board a = Board { unboard :: Array Index a } 

所以基本上一个Array。但也许我想添加一些其他数据,像这样:

data BoardWithInfo a = BWI { 
    bwiBoard :: Board a, 
    bwiRef :: String, 
    bwiStart :: Index 
} 

依此类推。我只想知道,是否有任何方便的优化功能来执行此操作,ArrayByteString以及组合数据 - 反之亦然。或者如果没有,我该怎么写自己的。

回答

2

你可以派生一个Show实例并保存它,或者从hackage中检查二进制模块。 IIRC它有Arrays的实例。你需要为你的newtype创建你的实例,但因为它只是一个包装器,所以这是一个简单的方法。二进制模块有很多很好的例子。

+0

+1; 'Data.Binary'非常适合使用,特别是如果您只关心在磁盘上放置位而不是匹配特定格式。 – acfoltzer 2011-04-13 14:01:56

+0

感谢您使用'Data.Binary'提示,这是一个很好的帮手。 – Lanbo 2011-04-13 14:29:44

3

你要使用Data.Binary与一对夫妇的实例来包装你BoardBoardWithInfo类型:

import Control.Monad 
import Data.Array 
import Data.Binary 

type Index = (Int, Int) 

newtype Board a = Board { unboard :: Array Index a } 
       deriving (Eq, Show) 

instance (Binary a) => Binary (Board a) where 
    get = liftM Board get 
    put b = put (unboard b) 

data BoardWithInfo a = BWI { bwiBoard :: Board a 
          , bwiRef :: String 
          , bwiStart :: Index } 
        deriving (Eq, Show) 

instance (Binary a) => Binary (BoardWithInfo a) where 
    get = liftM3 BWI get get get 
    put b = do 
    put (bwiBoard b) 
    put (bwiRef b) 
    put (bwiStart b) 

testBoard :: Board Int  
testBoard = Board $ listArray ((1,1),(10,10)) [1..100] 

testBWI :: BoardWithInfo Int 
testBWI = BWI testBoard "test" (1,1) 

-- returns True since the data survives encoding/decoding! 
testBinaryRoundtrip = testBWI == testBWI' 
    where 
    testBWI' = decode $ encode testBWI