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.
精彩评论