Add Semigroup and Monoid instances for Chunks

This commit is contained in:
Andrew Martin 2019-10-18 10:59:03 -04:00
parent 469da275e9
commit 6359787a02
2 changed files with 27 additions and 2 deletions

View file

@ -5,6 +5,7 @@
* Add big-endian and little-endian parsers for `Word128`. This includes * Add big-endian and little-endian parsers for `Word128`. This includes
both the single and multiple element variants. both the single and multiple element variants.
* Export `reverseCommitsOntoChunks` from the `Unsafe` module. * Export `reverseCommitsOntoChunks` from the `Unsafe` module.
* Add `Semigroup` and `Monoid` instances for `Chunks`.
## 0.3.0.0 -- 2019-10-17 ## 0.3.0.0 -- 2019-10-17

View file

@ -8,15 +8,17 @@
module Data.Bytes.Chunks module Data.Bytes.Chunks
( Chunks(..) ( Chunks(..)
, concat , concat
, reverse
, reverseOnto
) where ) where
import Prelude hiding (length,concat) import Prelude hiding (length,concat,reverse)
import GHC.ST (ST(..)) import GHC.ST (ST(..))
import Data.Bytes.Types (Bytes(..)) import Data.Bytes.Types (Bytes(..))
import Data.Primitive (ByteArray(..),MutableByteArray(..)) import Data.Primitive (ByteArray(..),MutableByteArray(..))
import GHC.Exts (ByteArray#,MutableByteArray#) import GHC.Exts (ByteArray#,MutableByteArray#)
import GHC.Exts (IsList,Int#,State#,Int(I#),(+#),(-#)) import GHC.Exts (Int#,State#,Int(I#),(+#))
import Control.Monad.ST.Run (runByteArrayST) import Control.Monad.ST.Run (runByteArrayST)
import qualified GHC.Exts as Exts import qualified GHC.Exts as Exts
@ -26,6 +28,15 @@ data Chunks
= ChunksCons {-# UNPACK #-} !Bytes !Chunks = ChunksCons {-# UNPACK #-} !Bytes !Chunks
| ChunksNil | ChunksNil
instance Semigroup Chunks where
ChunksNil <> a = a
cs@(ChunksCons _ _) <> ChunksNil = cs
as@(ChunksCons _ _) <> bs@(ChunksCons _ _) =
reverseOnto bs (reverse as)
instance Monoid Chunks where
mempty = ChunksNil
concat :: Chunks -> ByteArray concat :: Chunks -> ByteArray
concat x = ByteArray (concat# x) concat x = ByteArray (concat# x)
@ -69,6 +80,19 @@ copy# marr off (ChunksCons (Bytes{array,offset,length}) cs) s0 =
case Exts.copyByteArray# (unBa array) (unI offset) marr off (unI length) s0 of case Exts.copyByteArray# (unBa array) (unI offset) marr off (unI length) s0 of
s1 -> copy# marr (off +# unI length) cs s1 s1 -> copy# marr (off +# unI length) cs s1
-- | Reverse chunks but not the bytes within each chunk.
reverse :: Chunks -> Chunks
reverse = reverseOnto ChunksNil
-- | Variant of 'reverse' that allows the caller to provide
-- an initial list of chunks that the reversed chunks will
-- be pushed onto.
reverseOnto :: Chunks -> Chunks -> Chunks
reverseOnto !x ChunksNil = x
reverseOnto !x (ChunksCons y ys) =
reverseOnto (ChunksCons y x) ys
unI :: Int -> Int# unI :: Int -> Int#
unI (I# i) = i unI (I# i) = i