@@ -13,11 +13,14 @@ import Control.Applicative
1313
1414import Data.Maybe
1515import Data.Monoid hiding (Sum , Product , All )
16- import Data.Binary.Get hiding (Done )
16+ import Data.Binary.Get hiding (Done , Partial , skip )
17+ import qualified Data.Binary.Get as Get
1718import Data.Binary.Builder
18- import qualified Data.IntMap as IM
19+ import qualified Data.Map as M
1920import Data.ByteString.Base16
2021import qualified Data.ByteString.Lazy as BL
22+ import qualified Data.Vector.Generic as G
23+ import Control.Monad
2124
2225import Data.Int
2326import Data.Word
@@ -28,8 +31,8 @@ newtype K a b = K { unK :: a }
2831data (:*: ) f g x = f x :*: g x
2932data Exists f = forall a . Exists { getValue :: f a }
3033
31- newtype Flip r t = Flip { runFlip :: t -> r }
32- newtype NFlip r ts = NFlip { runNFlip :: ts @-> r }
34+ newtype ( :<- ) r t = Flip { runFlip :: t -> r }
35+ newtype ( :<-@ ) r ts = NFlip { runNFlip :: ts @-> r }
3336
3437type family (@-> ) (ts :: [* ]) (r :: * ) :: *
3538type instance '[] @-> r = r
@@ -55,23 +58,14 @@ mapAllF :: (forall a. f a -> b) -> All f ts -> [b]
5558mapAllF f Nil = []
5659mapAllF f (a :> as) = f a : mapAllF f as
5760
58- foldlAll :: (a -> b -> a ) -> a -> All (Flip b ) ts -> (ts @-> a )
61+ foldlAll :: (a -> b -> a ) -> a -> All (( :<- ) b ) ts -> (ts @-> a )
5962foldlAll f z Nil = z
6063foldlAll f z (Flip g :> gs) = \ x -> foldlAll f (f z (g x)) gs
6164
6265zipWithAll :: (forall a . f a -> g a -> h a ) -> All f ts -> All g ts -> All h ts
6366zipWithAll f Nil Nil = Nil
6467zipWithAll f (x :> xs) (y :> ys) = f x y :> zipWithAll f xs ys
6568
66- -- data Partial g b ts a = Partial { build :: g a, break :: ts @-> }
67- -- incremental All? When building, we know the argument and can compute the rest, when reading, we know the value and can compute the rest
68-
69- data Case f a ts = Case { cons :: ts @-> a , shape :: All f ts }
70- data Data f g a = forall ts . Data { elim :: forall r . a -> EliminatorWrapper ts r , sum :: All (g (Case f a )) ts }
71-
72- newtype EliminatorWrapper ts r = EliminatorWrapper { getEliminator :: Eliminator ts r }
73-
74-
7569-- All glory to glguy
7670apN :: Applicative f => f (ts @-> r ) -> All f ts -> f r
7771apN f Nil = f
@@ -80,14 +74,24 @@ apN f (x :> xs) = apN (f <*> x) xs
8074liftAn :: Applicative f => (ts @-> r ) -> All f ts -> f r
8175liftAn = apN . pure
8276
83-
84- merge :: All (NFlip r ) ts -> Eliminator ts r -> r
77+ merge :: All ((:<-@ ) r ) ts -> Eliminator ts r -> r
8578merge Nil acc = acc
8679merge (NFlip x :> xs) acc = merge xs (acc x)
8780
8881
89- eliminate :: Monoid m => All (K m :*: All (Flip m )) ts -> EliminatorWrapper ts m -> m
90- eliminate xs = merge (mapAll (\ (K i :*: shape) -> NFlip (foldlAll (<>) i shape)) xs) . getEliminator
82+ -- incremental All? When building, we know the argument and can compute the rest, when reading, we know the value and can compute the rest
83+
84+ data Partial p g a ts = Partial { build :: ! (g a ), break :: ! (ts @-> p ), make :: ! (ts @-> a ) } -- forall xs. uncurryN make xs == runGet build . toLazyByteString $ uncurryN break xs
85+
86+ newtype EliminatorWrapper ts r = EliminatorWrapper { getEliminator :: Eliminator ts r }
87+
88+ alt :: (ts @-> a ) -> All Prickler ts -> Partial Put Get a ts
89+ alt cons shape = Partial builder breaker cons
90+ where
91+ builder = liftAn cons (mapAll get shape)
92+ breaker = foldlAll (<>) mempty (mapAll (Flip . put) shape)
93+
94+
9195
9296
9397
@@ -98,14 +102,31 @@ eliminate xs = merge (mapAll (\(K i :*: shape) -> NFlip (foldlAll (<>) i shape))
98102
99103
100104
105+ data State a = State { written :: {-# UNPACK #-} ! Int64 , builder :: ! Builder , contents :: a }
101106
107+ instance Functor State where
108+ fmap f (State w b v) = State w b (f v)
102109
110+ newtype PutM a = PutM { runPut :: Int64 -> State a }
103111
112+ instance Functor PutM where
113+ fmap f (PutM g) = PutM (fmap f . g)
104114
115+ instance Applicative PutM where
116+ pure x = PutM (\ w -> State w mempty x)
117+ PutM f <*> PutM x = PutM $ \ w -> case f w of State w1 b1 f' -> case x w1 of State w2 b2 x' -> State w2 (b1 <> b2) (f' x')
105118
119+ instance Monad PutM where
120+ return = pure
121+ PutM x >>= f = PutM (\ w -> case x w of State w1 b1 x' -> case f x' of PutM f' -> case f' w1 of State w2 b2 x'' -> State w2 (b1 <> b2) x'')
106122
123+ type Put = PutM ()
107124
108- data Prickler a = Prickler { get :: Get a , put :: a -> Builder } -- laws: get . put . get == get, put . get . put == put
125+ instance Monoid Put where
126+ mempty = pure ()
127+ mappend = (>>)
128+
129+ data Prickler a = Prickler { get :: Get a , put :: a -> Put } -- laws: get . put . get == get, put . get . put == put
109130
110131expect :: Eq a => a -> Prickler a -> Prickler ()
111132expect x (Prickler ga pa) = Prickler (do y <- ga; if x == y then return () else fail " Expectation failed" ) (const (pa x))
@@ -125,23 +146,121 @@ pair (Prickler ga pa) (Prickler gb pb) = Prickler (liftA2 (,) ga gb) (\(x, y) ->
125146type Contiguous = (:$: )
126147type Indexed i = (:*: ) (K i )
127148
128- contiguousData :: Integral i => Prickler i -> Data Prickler Contiguous a -> Prickler a
129- contiguousData = undefined
130149
131- taggedData :: Integral i => Prickler i -> Data Prickler (Indexed i ) a -> Prickler a
132- taggedData (Prickler gi pi ) (Data elim sum ) = Prickler getter (eliminate (mapAll (adjust pi ) sum ) . elim)
150+ untagged :: (forall r . a -> (ts @-> r ) -> r ) -> Partial Put Get a ts -> Prickler a
151+ untagged elim (Partial build break _) = Prickler build (flip elim break )
152+
153+
154+ tagged :: Ord i => Prickler i -> (forall r . a -> EliminatorWrapper ts r ) -> All (Indexed i (Partial Put Get a )) ts -> Prickler a
155+ tagged (Prickler gi pi ) elim sum = Prickler getter (merged (mapAll (adjust pi ) sum ) . elim)
133156 where
134- adjust :: (i -> Builder ) -> (K i :*: Case Prickler a ) ts -> (K Builder :*: All (Flip Builder )) ts
135- adjust pi (K i :*: Case _ shape) = K (pi i) :*: mapAll (Flip . put) shape
157+ merged :: All ((:<-@ ) r ) ts -> EliminatorWrapper ts r -> r
158+ merged rs (EliminatorWrapper elim) = merge rs elim
159+
160+ adjust :: (i -> Put ) -> (K i :*: Partial Put Get a ) ts -> (Put :<-@ ts )
161+ adjust pi (K i :*: Partial _ breaker _) = NFlip breaker
162+
136163
137- ps = IM . fromList (mapAllF (\ (K x :*: y) -> (fromIntegral x, Exists y)) sum )
164+ ps = M . fromList (mapAllF (\ (K x :*: y) -> (x, Exists y)) sum )
138165
139166 getter = do
140167 tag <- gi
141- case IM .lookup ( fromIntegral tag) ps of
142- Nothing -> fail $ " Invalid tag: " ++ show ( fromIntegral tag :: Integer )
143- Just (Exists (Case cons shape )) -> liftAn cons (mapAll get shape)
168+ case M .lookup tag ps of
169+ Nothing -> fail $ " Invalid tag! "
170+ Just (Exists (Partial maker _ _ )) -> maker
144171
145172
173+ taggedSized :: (Show i , Ord i , Integral s ) => Prickler i -> Prickler s -> (forall r . a -> EliminatorWrapper ts r ) -> All (Indexed i (Partial Put Get a )) ts -> Prickler a
174+ taggedSized (Prickler gi pi ) (Prickler gs ps) elim sum = Prickler getter (merged (mapAll (adjust pi ) sum ) . elim)
175+ where
176+ merged :: All ((:<-@ ) r ) ts -> EliminatorWrapper ts r -> r
177+ merged rs (EliminatorWrapper elim) = merge rs elim
178+
179+ adjust :: (i -> Put ) -> (K i :*: Partial Put Get a ) ts -> (Put :<-@ ts )
180+ adjust pi (K i :*: Partial _ breaker _) = NFlip breaker
181+
182+
183+ ps = M. fromList (mapAllF (\ (K x :*: y) -> (x, Exists y)) sum )
184+
185+ getter = do
186+ tag <- gi
187+ size <- gs
188+ case M. lookup tag ps of
189+ Nothing -> fail $ " Invalid tag! " ++ show tag
190+ Just (Exists (Partial maker _ _)) -> do
191+ bs <- getLazyByteString (fromIntegral size)
192+ return $ runGet maker bs
193+
194+
195+
196+ alignedGet :: Int -> Get a -> Get a
197+ alignedGet n g = do
198+ br <- fromIntegral <$> bytesRead
199+ Get. skip $ n - br `rem` n
200+ g
201+
202+
203+ bytesWritten :: PutM Int64
204+ bytesWritten = PutM (\ w -> State w mempty w)
205+
206+ singletonPut :: Word8 -> Put
207+ singletonPut x = PutM (\ w -> State (w + 1 ) (singleton x) () )
208+
209+ alignedPut :: Int -> PutM a -> PutM a
210+ alignedPut n p = do
211+ bw <- fromIntegral <$> bytesWritten
212+ replicateM_ (n - (bw `rem` n)) (singletonPut 0 )
213+ p
214+
146215(#) :: a -> g x -> (K a :*: g ) x
147216i # x = K i :*: x
217+
218+
219+ word8 = Prickler getWord8 singletonPut
220+
221+ word16be = Prickler getWord16be (\ x -> PutM (\ w -> State (w + 2 ) (putWord16be x) () ))
222+ word16le = Prickler getWord16le (\ x -> PutM (\ w -> State (w + 2 ) (putWord16le x) () ))
223+
224+ word32be = Prickler getWord32be (\ x -> PutM (\ w -> State (w + 4 ) (putWord32be x) () ))
225+ word32le = Prickler getWord32le (\ x -> PutM (\ w -> State (w + 4 ) (putWord32le x) () ))
226+
227+ word64be = Prickler getWord64be (\ x -> PutM (\ w -> State (w + 8 ) (putWord64be x) () ))
228+ word64le = Prickler getWord64le (\ x -> PutM (\ w -> State (w + 8 ) (putWord64le x) () ))
229+
230+ int8 :: Prickler Int8
231+ int8 = wrap fromIntegral fromIntegral word8
232+
233+ int16be , int16le :: Prickler Int16
234+ int16be = wrap fromIntegral fromIntegral word16be
235+ int16le = wrap fromIntegral fromIntegral word16le
236+
237+ int32be , int32le :: Prickler Int32
238+ int32be = wrap fromIntegral fromIntegral word32be
239+ int32le = wrap fromIntegral fromIntegral word32le
240+
241+ int64be , int64le :: Prickler Int64
242+ int64be = wrap fromIntegral fromIntegral word64be
243+ int64le = wrap fromIntegral fromIntegral word64le
244+
245+ float :: Prickler Float
246+ float = error " foo"
247+
248+ double :: Prickler Double
249+ double = error " bar"
250+
251+ byteString :: Integral i => Prickler i -> Prickler BL. ByteString
252+ byteString (Prickler gi pi ) = Prickler getter putter
253+ where
254+ getter = do len <- gi; getLazyByteString (fromIntegral len)
255+ putter xs = let len = BL. length xs in pi (fromIntegral len) <> PutM (\ w -> State (w + fromIntegral len) (fromLazyByteString xs) () )
256+
257+ remainingByteString :: Prickler BL. ByteString
258+ remainingByteString = Prickler getRemainingLazyByteString putter
259+ where
260+ putter xs = undefined
261+
262+ gvector :: (Integral i , G. Vector v a ) => Prickler i -> Prickler a -> Prickler (v a )
263+ gvector (Prickler gi pi ) (Prickler ga pa) = Prickler getter putter
264+ where
265+ getter = do len <- gi; G. replicateM (fromIntegral len) ga
266+ putter xs = do pi (fromIntegral $ G. length xs); G. mapM_ pa xs
0 commit comments