我有一个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
}
等等。我只是想知道,有没有方便的优化函数来执行此操作,Array
到ByteString
和组合数据 - 反之亦然。或者如果没有,我该怎么写自己的。
答案 0 :(得分:3)
您需要将Data.Binary
与几个实例一起用于包裹Board
和BoardWithInfo
类型:
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创建你的实例,但因为它只是一个包装器,所以这是一个明智的选择。二进制模块具有很多示例的优秀文档。