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结合数据——反之亦然。或者我自己怎么写,如果没有的话。

4

2 回答 2

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
于 2011-04-13T14:30:35.987 回答
2

您可以派生一个 Show 实例并将其保存,或者从 hackage 检查二进制模块。IIRC 它有数组的实例。您需要为您的新类型创建您的实例,但由于它只是一个包装器,所以它是不费吹灰之力的。二进制模块具有出色的文档和大量示例。

于 2011-04-13T13:52:49.083 回答