on master help sign in
Add Serialize instance for Integer
commit9c67608ffa072f14c398e20529f7da7a7d3df9e7 authorAdithya Kumar <adithya@composewell.com> dateSun 10 Sep 2023, 17:31 (3 years ago) parent3043a3f
3 files changed+74−1
core/src/Streamly/Internal/Data/Serialize.hs+65−1 core/streamly-core.cabal+6 test/Streamly/Test/Data/Serialize.hs+3
core/src/Streamly/Internal/Data/Serialize.hs+65−1
@@ -20,9 +20,20 @@ module Streamly.Internal.Data.Serialize
2020--------------------------------------------------------------------------------
2121
2222import Data.Proxy (Proxy)
23−import Streamly.Internal.Data.Serialize.Type
23+import Streamly.Internal.Data.Array (Array(..))
24+import Streamly.Internal.Data.Unbox (MutableByteArray(..))
25+import GHC.Exts (Int(..), sizeofByteArray#, unsafeCoerce#)
26+
2427import qualified Streamly.Internal.Data.Serialize.TH as Serialize
2528
29+#if __GLASGOW_HASKELL__ >= 900
30+import GHC.Num.Integer (Integer(..))
31+#else
32+import GHC.Integer.GMP.Internals (Integer(..), BigNat(..))
33+#endif
34+
35+import Streamly.Internal.Data.Serialize.Type
36+
2637--------------------------------------------------------------------------------
2738-- Common instances
2839--------------------------------------------------------------------------------
@@ -52,3 +63,56 @@ $(Serialize.deriveSerialize ''Either)
5263$(Serialize.deriveSerializeWith
5364 (Serialize.defaultConfig {Serialize.unconstrained = ["t"]})
5465 ''Proxy)
66+
67+--------------------------------------------------------------------------------
68+-- Integer
69+--------------------------------------------------------------------------------
70+
71+data LiftedInteger
72+ = LIS Int
73+ | LIP (Array Word)
74+ | LIN (Array Word)
75+
76+$(Serialize.deriveSerialize ''LiftedInteger)
77+
78+#if __GLASGOW_HASKELL__ >= 900
79+
80+liftInteger :: Integer -> LiftedInteger
81+liftInteger (IS x) = LIS (I# x)
82+liftInteger (IP x) =
83+ LIP (Array (MutableByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
84+liftInteger (IN x) =
85+ LIN (Array (MutableByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
86+
87+unliftInteger :: LiftedInteger -> Integer
88+unliftInteger (LIS (I# x)) = IS x
89+unliftInteger (LIP (Array (MutableByteArray x) _ _)) = IP (unsafeCoerce# x)
90+unliftInteger (LIN (Array (MutableByteArray x) _ _)) = IN (unsafeCoerce# x)
91+
92+#else
93+
94+liftInteger :: Integer -> LiftedInteger
95+liftInteger (S# x) = LIS (I# x)
96+liftInteger (Jp# (BN# x)) =
97+ LIP (Array (MutableByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
98+liftInteger (Jn# (BN# x)) =
99+ LIN (Array (MutableByteArray (unsafeCoerce# x)) 0 (I# (sizeofByteArray# x)))
100+
101+unliftInteger :: LiftedInteger -> Integer
102+unliftInteger (LIS (I# x)) = S# x
103+unliftInteger (LIP (Array (MutableByteArray x) _ _)) =
104+ Jp# (BN# (unsafeCoerce# x))
105+unliftInteger (LIN (Array (MutableByteArray x) _ _)) =
106+ Jn# (BN# (unsafeCoerce# x))
107+
108+#endif
109+
110+instance Serialize Integer where
111+ {-# INLINE size #-}
112+ size i a = size i (liftInteger a)
113+
114+ {-# INLINE deserialize #-}
115+ deserialize off arr end = fmap unliftInteger <$> deserialize off arr end
116+
117+ {-# INLINE serialize #-}
118+ serialize off arr val = serialize off arr (liftInteger val)
core/streamly-core.cabal+6
@@ -461,6 +461,12 @@ library
461461 -- XXX to be removed
462462 , containers >= 0.6.0 && < 0.7
463463 , heaps >= 0.3 && < 0.5
464+
465+ if impl(ghc >= 9.0)
466+ build-depends: ghc-bignum >= 1.0 && < 2
467+ else
468+ build-depends: integer-gmp >= 1.0 && < 1.2
469+
464470 if !flag(use-unliftio)
465471 build-depends: monad-control >= 1.0 && < 1.1
466472
test/Streamly/Test/Data/Serialize.hs+3
@@ -170,6 +170,9 @@ testCases = do
170170 it "HigherOrderType"
171171 $ roundtrip $ HigherOrderType (Identity 5) (Identity 'e')
172172
173+ prop "Integer"
174+ $ \(x :: Integer) -> roundtrip x
175+
173176 prop "Array Int"
174177 $ \(x :: [Int]) -> roundtrip (Array.fromList x)
175178