开发者

Datatype to ByteString

I have a newtype I'd like to save in a file, something like this:

type Index = (Int, Int)

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

So basically an Array. But maybe I want to add some other data开发者_如何学Go one day like this:

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

And so on. I just want to know, are there any convenient, optimised functions to do this, Array to ByteString and combined data - and the other way around. Or how to write my own, if there are not.


You'll want to use Data.Binary with a couple instances to wrap your Board and BoardWithInfo types:

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


You could derive a Show instance and save it as such, or check the binary module from hackage. IIRC it has instance for Arrays. You need to create your instance for your newtype, but as it's just a wrapper, it's a no-brainer. The binary module has excellent documentation with lots of examples.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜