RefSerialize 0.2.5 → 0.2.6
raw patch · 3 files changed
+134/−51 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Data.RefSerialize: instance [incoherent] (Serialize a) => Serialize [a]
- Data.RefSerialize: instance [incoherent] (Show a, Read a) => Serialize a
- Data.RefSerialize: instance [incoherent] Serialize String
+ Data.RefSerialize: instance [overlap ok] (Serialize a) => Serialize (Maybe a)
+ Data.RefSerialize: instance [overlap ok] (Serialize a) => Serialize [a]
+ Data.RefSerialize: instance [overlap ok] (Serialize a, Ord a, Serialize b) => Serialize (Map a b)
+ Data.RefSerialize: instance [overlap ok] (Serialize a, Serialize b) => Serialize (Either a b)
+ Data.RefSerialize: instance [overlap ok] (Serialize a, Serialize b) => Serialize (a, b)
+ Data.RefSerialize: instance [overlap ok] Serialize ()
+ Data.RefSerialize: instance [overlap ok] Serialize Bool
+ Data.RefSerialize: instance [overlap ok] Serialize Char
+ Data.RefSerialize: instance [overlap ok] Serialize Double
+ Data.RefSerialize: instance [overlap ok] Serialize Float
+ Data.RefSerialize: instance [overlap ok] Serialize Int
+ Data.RefSerialize: instance [overlap ok] Serialize Integer
+ Data.RefSerialize: instance [overlap ok] Serialize Ordering
+ Data.RefSerialize: instance [overlap ok] Serialize String
+ Data.RefSerialize: readSR :: (Read a) => ST a
+ Data.RefSerialize: showSR :: (Show a) => a -> ST String
Files
- Data/RefSerialize.hs +121/−42
- Data/Serialize.hs +1/−1
- RefSerialize.cabal +12/−8
Data/RefSerialize.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances -XIncoherentInstances #-}+{-# OPTIONS -fglasgow-exts -XOverlappingInstances #-} ----------------------------------------------------------------------------- --@@ -126,6 +126,8 @@ ,rreadp )+ ,showSR+ ,readSR ,rShow ,rRead ,insertVar@@ -144,6 +146,7 @@ import Unsafe.Coerce import Data.Char(isAlpha, isSpace, isAlphaNum) import Numeric(readHex,showHex)+import Data.Map class Serialize c where@@ -158,6 +161,8 @@ rreadp :: ST c -- ^ read a variable in the where section (to use for deserializing rshowp output). @rreadp = readVar readp@ -- default definition rreadp = readVar readp++ {- #ifdef Axioms @@ -189,16 +194,17 @@ readHexp :: (Num a, Integral a) => ST a readHexp = ST(\(Stat(c,s,v)) -> let l= readHex s- in if null l then Left . Error $ "not readable: " ++ s+ in if Prelude.null l then Left . Error $ "not readable: " ++ s else let ((x,str2):_)= l in Right(Stat(c,dropWhile isSpace str2,v),x) ) <?> "readHexp "-+-- |if a is an instance of Read, readSR can be used as the readp method+-- the drawback is that the data inside is not inspected for common references+-- so it is recommended to create your own readp method for your complex data structures readSR :: Read a => ST a- readSR = ST(\(Stat(c,s,v)) -> let l= readsPrec 1 s- in if null l then Left . Error $ "not readable: " ++ s+ in if Prelude.null l then Left . Error $ "not readable: " ++ s else let ((x,str2):_)= l in Right(Stat(c,dropWhile isSpace str2,v),x) ) <?> "readp: readsPrec "@@ -218,6 +224,9 @@ showHexp :: (Num a,Integral a) => a -> ST String showHexp var= ST(\(Stat(c,s,v)) -> Right(Stat(c,s,v),showHex var "")) <?> "showHexp " +-- |if a is an instance of Show, showSR can be used as the showp method+-- the drawback is that the data inside is not inspected for common references+-- so it is recommended to create your own readp method for your complex data structures showSR :: Show a => a -> ST String showSR var= ST(\(Stat(c,s,v)) -> Right(Stat(c,s,v),show var)) <?> "showp: show " @@ -229,52 +238,17 @@ let scontext= M.assocs c show1 c= concatMap (\(n,(_,v))->"v"++ show n++"= "++v++"; ") scontext vars= show1 c- strContext= if null vars then "" else " where {"++vars ++ "}"+ strContext= if Prelude.null vars then "" else " where {"++vars ++ "}" in str ++ strContext Left (Error s) -> error s --- -------------Instances -instance Serialize String where- showp = showSR- readp = readSR -instance Serialize a => Serialize [a] where- showp []= return "[]"- showp (x:xs)= do- s1<- showp x- sn<- mapM f xs- return $ "["++ s1++ concat sn ++"]"- where- f x=do str <- showp (x:: a)- return $ ", "++str - readp = (brackets $ commaSep $ readp) <?> "readp:: [] "-- rshowp = insertVar rshowp1 where- rshowp1 []= insertVar return "[]"- rshowp1 (x:xs)= do- s1<- rshowp x- sn<- mapM f xs- return $ "["++ s1++ concat sn ++"]"- where- f x= do str <- rshowp (x:: a)- return $ ", "++str--- rreadp = (readVar $ brackets $ commaSep $ rreadp) <?> "rreadp:: [] "---instance (Show a, Read a) => Serialize a where- showp = showSR- readp = readSR------ | insert a variable at this position. The expression value is inserted the where part if it is not already+-- | insert a variable at this position. The expression value is inserted in the "where" section if it is not already -- created. If the address of this object being parsed correspond with an address already parsed and -- it is in the where section, then the same variable name is used -- @runW showp (1::Int) -> "1"@@ -330,6 +304,111 @@ case M.lookup x c of Nothing -> Nothing justx -> justx+++-- -------------Instances+++instance Serialize String where+ showp = showSR+ readp = readSR++instance Serialize a => Serialize [a] where+ showp []= return "[]"+ showp (x:xs)= do+ s1<- rshowp x+ sn<- mapM f xs+ return $ "["++ s1++ concat sn ++"]"+ where+ f x= do str <- rshowp (x:: a)+ return $ ", "++str++ readp = (readVar $ brackets $ commaSep $ rreadp) <?> "rreadp:: [] "++++++instance (Serialize a, Serialize b) => Serialize (a, b) where+ showp (x, y)= do+ sx <- rshowp x+ sy <- rshowp y+ return $ "("++ sx ++ ", " ++ sy ++ ")"++ readp = parens $ do+ x <- rreadp+ comma+ y <- rreadp+ return (x,y)++++instance (Serialize a, Ord a, Serialize b) => Serialize (Map a b) where+ showp m= showp $ M.toList m+ readp= do+ list <- readp :: ST [(a,b)]+ return $ M.fromList list+++++instance Serialize a => Serialize (Maybe a) where+ showp Nothing = return "Nothing"+ showp (Just x) = showp x >>= \sx -> return $ "Just " ++ sx+ readp = choice [rNothing, rJust] where+ rNothing = symbol "Nothing" >> return Nothing+ rJust = symbol "Just" >> readp >>= \x -> return $ Just x++instance (Serialize a, Serialize b) => Serialize (Either a b) where+ showp (Left x) = rshowp x >>= \sx -> return $ "Left " ++ sx++ showp (Right x) = rshowp x >>= \sx -> return $ "Right " ++ sx++ readp = choice [rLeft, rRight] where+ rLeft = symbol "Left" >> rreadp >>= \x -> return $ Left x+ rRight = symbol "Right" >> rreadp >>= \x -> return $ Right x++++++instance Serialize Bool where+ showp = showSR+ readp = readSR++instance Serialize Char where+ showp = showSR+ readp = readSR++instance Serialize Double where+ showp = showSR+ readp = readSR++instance Serialize Float where+ showp = showSR+ readp = readSR++instance Serialize Int where+ showp = showSR+ readp = readSR+++instance Serialize Integer where+ showp = showSR+ readp = readSR++instance Serialize Ordering where+ showp = showSR+ readp = readSR++instance Serialize () where+ showp = showSR+ readp = readSR+++++
Data/Serialize.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances #-}+{-# OPTIONS -fglasgow-exts #-} module Data.Serialize where import GHC.Exts import Unsafe.Coerce
RefSerialize.cabal view
@@ -1,35 +1,39 @@ name: RefSerialize-version: 0.2.5+version: 0.2.6 synopsis: Write to and read from Strings maintaining internal memory references description:- Read, Show and Data.Binary do not check for repeated references to the same address.+ Read, Show and Data.Binary do not check for internal data references to the same address. As a result, the data is duplicated when serialized. This is a waste of space in the filesystem and also a waste of serialization time. but the worst consequence is that, when the serialized data is read, it allocates multiple copies for the same object when referenced multiple times. Because multiple referenced data is very typical in a pure language such is Haskell, this means that the resulting data loose the beatiful economy of space and processing time that referential transparency permits. .- Every instance of Show/Read is also a instance of Data.RefSerialize.+ Every instance of Show/Read can be an instance of Data.RefSerialize. . This package allows the serialization and deserialization of large data structures without duplication of data, with- the result of optimized performance and memory usage. It is also useful for debugging purposes.+ the result of optimized performance and memory usage. Since the serialized data is also human readable, It is also+ useful for debugging purposes. .- There are automatic derived instances for instances of Read/Show. Lists of non-chars have its own instance. The deserializer contains a subset of Parsec.Token for defining deserializing parsers. . the serialized string has the form: . @expr( var1, ...varn) where var1=value1,..valn=valueN @ .- so that the string can be EVALuated.+ so that the string can agree with the haskell syntax. . See demo.hs and tutorial. . in this release: .- * Proper trailing withespace handlling for instances of Read+ * bug corrected: empty lists were written with two indirections (insertVar . insertVar). That caused an error in readp .- * Error handllig for instances of Read.+ * removed the problematic instance (Show a, Read a) => Serialize a+ .+ * Added instances for standard datatypes,+ .+ * instance of Serialize [a] changed . To do: .