数据类型为ByteString

时间:2011-04-13 13:28:39

标签: arrays haskell binary bytestring

我有一个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 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

您可以派生一个Show实例并将其保存,或者从hackage中检查二进制模块。 IIRC它有阵列的实例。你需要为你的newtype创建你的实例,但因为它只是一个包装器,所以这是一个明智的选择。二进制模块具有很多示例的优秀文档。