2

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 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.

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
Lanbo
  • 15,118
  • 16
  • 70
  • 147

2 Answers2

3

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
acfoltzer
  • 5,588
  • 31
  • 48
2

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.

Masse
  • 4,334
  • 3
  • 30
  • 41
  • +1; `Data.Binary` is really nice to work with, particularly if you just care about putting bits on disk rather than matching a specific format. – acfoltzer Apr 13 '11 at 14:01
  • Thanks for the tip with `Data.Binary`, it is a great helper. – Lanbo Apr 13 '11 at 14:29