{-# OPTIONS -fglasgow-exts -XOverlappingInstances -XUndecidableInstances #-}
module Main where
import System.Mem.StableName
import System.IO.Unsafe
import Data.RefSerialize
--simple data structure
data S= S Int Int deriving ( Show, Eq)
instance Serialize S where
showp (S x y)= do
xs <- rshowp x -- rshowp parsers can be inside showp parser
ys <- rshowp y
return $ "S "++xs++" "++ys
readp = do
symbol "S"
x <- rreadp
y <- rreadp
return $ S x y
----------------- a more complex structure with mixed record and array with default read/show type serialization ----
data Data = Data Int String deriving (Read,Show)
data Stat a= Workflows [String]
| Stat{ wfName :: String, state:: Int, index :: Int, recover:: Bool, sync :: Bool , resource :: [a]}
| I a
deriving (Read,Show)
-- the parser definitions for this structure
instance Serialize a => Serialize (Stat a) where
showp (Workflows list)= do
str <- showp list
return $ "StatWorkflows "++ str
showp (I x) = return $ "I " ++ rShow x
showp (Stat wfName state index recover sync resource)= do
parsea <- rshowp resource --creates a variable
return $ "Stat "++ show wfName ++" "++ show state++" "++show index++" "++show recover++" "++ show sync ++ parsea
readp = choice [rStat, rData, rWorkflows] where --choice is a exported parser (Parsec.Token interface is included)
rStat= do
symbol "Stat"
wfName <- stringLiteral -- various parsec parsers are used
state <- integer
index <- integer
recover <- bool
sync <- bool
resource <- rreadp -- read the variable
return $ Stat wfName (fromIntegral state) (fromIntegral index) recover sync resource
rData= do
symbol "I"
a <- readp
return $ I a
rWorkflows= do
symbol "StatWorkflows"
list <- readp
return $ Workflows list
main= do
let x = (5 :: Int)
putStrLn $ runW $ showp $ S x x
let xss = [[x,x],[x,x]]
let str= rShow xss
putStrLn str
let y = rRead " v10 where {v6= [ v8, v8]; v8= 5; v9= [v8, v8]; v10= [ v6, v9]; }" ::[[Int]]
print y
putStrLn "instance (Show a, Read a) => Serialize a "
putStr "rShow 10="
putStrLn $ rShow (10 :: Int)
putStrLn "serialize String's"
let x= "hello"
let str= rShow x
putStrLn $ "rShow "++ str++"= "++str
let y= rRead str :: String
print y
print $ x==y
putStrLn "serialize [a] "
let xs= take 2 $ repeat (Data 0 "")
let xss= take 2 $ repeat xs
let str= rShow xss
putStrLn str
let x= rRead str :: [[Data]]
let x= 1 :: Int
let xs= take 5 $ repeat x
print xs
putStr "rShow xs="
let str= rShow xs
putStrLn str
putStrLn "using the RefSerialize instance of Stat (see definition in this file)"
let stat0 = Stat{ wfName="", state=0, index=0, recover=False, resource=[], sync= True}
let data0= Data 0 ""
let str = rShow stat0{resource= (take 2 $ repeat data0) ++ (take 2 $ repeat (Data 1 "1")) }
putStrLn "references to the same address are identified by rshowp. they point to the same variable in the serialized data"
putStrLn $ "rShow "++ show data0 ++"= "++ str
let stat1= rRead str :: Stat Data
putStrLn "data that point to the same variable when serializeds point to the same memory address when deserialized"
let addr x= (hashStableName . unsafePerformIO . makeStableName) x
let x= (resource stat1 !! 0)
putStr "first element of the resource list= "
print x
putStr "address of this element= "
print $ addr x
let y= (resource stat1 !! 1)
putStr "second element of the resource list= "
print y
putStr "address of this element= "
print $ addr y
print $ addr y== addr x