packages feed

RefSerialize-0.2.4: demo.hs

{-# 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