on master help sign in
Remove Storable constraint from Unbox typeclass
commitf7f264fefd3d64129ec4e2f5cb3739c86fda7f83 authorAdithya Kumar <adithya@composewell.com> dateWed 28 Dec 2022, 20:16 (4 years ago) parentc2f7914
11 files changed+117−116
core/src/Streamly/Internal/Data/Array.hs+2−1 core/src/Streamly/Internal/Data/Array/Mut/Type.hs+15−26 core/src/Streamly/Internal/Data/Fold.hs+4−4 core/src/Streamly/Internal/Data/Ring/Unboxed.hs+2−2 core/src/Streamly/Internal/Data/Stream/Eliminate.hs+2−1 core/src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+4−4 core/src/Streamly/Internal/Data/Unboxed.hs+78−72 src/Streamly/Internal/Data/Stream/IsStream/Common.hs+2−1 src/Streamly/Internal/Data/Stream/IsStream/Eliminate.hs+2−1 src/Streamly/Internal/Data/Stream/IsStream/Reduce.hs+4−3 test/Streamly/Test/Prelude/Serial.hs+2−1
core/src/Streamly/Internal/Data/Array.hs+2−1
@@ -125,6 +125,7 @@ import Data.Functor.Identity (Identity)
125125import Data.Word (Word8)
126126import Foreign.C.String (CString)
127127import Foreign.Ptr (castPtr)
128+import Foreign.Storable (Storable)
128129import Streamly.Internal.Data.Unboxed
129130 ( Unbox
130131 , castContents
@@ -273,7 +274,7 @@ last = getIndexRev 0
273274--
274275{-# INLINE writeLastN #-}
275276writeLastN ::
276− (Unbox a, MonadIO m) => Int -> Fold m a (Array a)
277+ (Storable a, Unbox a, MonadIO m) => Int -> Fold m a (Array a)
277278writeLastN n
278279 | n <= 0 = fmap (const mempty) FL.drain
279280 | otherwise = A.unsafeFreeze <$> Fold step initial done
core/src/Streamly/Internal/Data/Array/Mut/Type.hs+15−26
@@ -223,7 +223,6 @@ import Foreign.Ptr (plusPtr, minusPtr, nullPtr)
223223import Streamly.Internal.Data.Unboxed
224224 ( MutableByteArray(..)
225225 , Unbox
226− , alignment
227226 , castContents
228227 , getMutableByteArray#
229228 , peekWith
@@ -414,11 +413,9 @@ nil = Array Unboxed.nil 0 0 0
414413--
415414-- /Pre-release/
416415{-# INLINE newPinnedBytes #-}
417−newPinnedBytes :: forall m a. (MonadIO m, Unbox a) => Int -> m (Array a)
416+newPinnedBytes :: MonadIO m => Int -> m (Array a)
418417newPinnedBytes bytes = do
419− contents <-
420− liftIO
421− $ Unboxed.newAlignedPinnedBytes bytes (alignment (undefined :: a))
418+ contents <- liftIO $ Unboxed.newPinnedBytes bytes
422419 return $ Array
423420 { arrContents = contents
424421 , arrStart = 0
@@ -443,7 +440,10 @@ newAlignedPinned =
443440--
444441{-# INLINE newPinned #-}
445442newPinned :: forall m a. (MonadIO m, Unbox a) => Int -> m (Array a)
446−newPinned = newAlignedPinned (alignment (undefined :: a))
443+newPinned =
444+ newArrayWith
445+ (\s _ -> liftIO $ Unboxed.newPinnedBytes s)
446+ (error "newPinned: alignSize is not used")
447447
448448-- | Allocates an empty unpinned array that can hold 'count' items. The memory
449449-- of the array is uninitialized.
@@ -705,14 +705,14 @@ roundDownTo elemSize size = size - (size `mod` elemSize)
705705-- Since this is not inlined Unboxed consrraint leads to dictionary passing
706706-- which complicates some inspection tests.
707707--
708−{-# NOINLINE reallocAligned #-}
709−reallocAligned :: Int -> Int -> Int -> Array a -> IO (Array a)
710−reallocAligned elemSize alignSize newCapacityInBytes Array{..} = do
708+{-# NOINLINE reallocExplicit #-}
709+reallocExplicit :: Int -> Int -> Array a -> IO (Array a)
710+reallocExplicit elemSize newCapacityInBytes Array{..} = do
711711 assertM(arrEnd <= arrBound)
712712
713713 -- Allocate new array
714714 let newCapMaxInBytes = roundUpLargeArray newCapacityInBytes
715− contents <- Unboxed.newAlignedPinnedBytes newCapMaxInBytes alignSize
715+ contents <- Unboxed.newPinnedBytes newCapMaxInBytes
716716 let !(MutableByteArray mbarrFrom#) = arrContents
717717 !(MutableByteArray mbarrTo#) = contents
718718
@@ -745,8 +745,7 @@ reallocAligned elemSize alignSize newCapacityInBytes Array{..} = do
745745--
746746{-# INLINABLE realloc #-}
747747realloc :: forall m a. (MonadIO m, Unbox a) => Int -> Array a -> m (Array a)
748−realloc bytes arr =
749− liftIO $ reallocAligned (SIZE_OF(a)) (alignment (undefined :: a)) bytes arr
748+realloc bytes arr = liftIO $ reallocExplicit (SIZE_OF(a)) bytes arr
750749
751750-- | @reallocWith label capSizer minIncrBytes array@. The label is used
752751-- in error messages and the capSizer is used to determine the capacity of the
@@ -1872,18 +1871,12 @@ writeWith elemCount =
18721871
18731872 initial = do
18741873 when (elemCount < 0) $ error "writeWith: elemCount is negative"
1875− liftIO $ newAlignedPinned (alignment (undefined :: a)) elemCount
1874+ liftIO $ newPinned elemCount
18761875 step arr@(Array _ start end bound) x
18771876 | INDEX_NEXT(end,a) > bound = do
18781877 let oldSize = end - start
18791878 newSize = max (oldSize * 2) 1
1880− arr1 <-
1881− liftIO
1882− $ reallocAligned
1883− (SIZE_OF(a))
1884− (alignment (undefined :: a))
1885− newSize
1886− arr
1879+ arr1 <- liftIO $ reallocExplicit (SIZE_OF(a)) newSize arr
18871880 insertElem arr1 x
18881881 step arr x = insertElem arr x
18891882 extract = liftIO . rightSize
@@ -2008,18 +2001,14 @@ putSliceUnsafe src srcStartBytes dst dstStartBytes lenBytes = liftIO $ do
20082001
20092002-- | Copy two arrays into a newly allocated array.
20102003{-# INLINE spliceCopy #-}
2011−spliceCopy :: forall m a. (MonadIO m, Unbox a) =>
2004+spliceCopy :: forall m a. MonadIO m =>
20122005 Array a -> Array a -> m (Array a)
20132006spliceCopy arr1 arr2 = liftIO $ do
20142007 let start1 = arrStart arr1
20152008 start2 = arrStart arr2
20162009 len1 = arrEnd arr1 - start1
20172010 len2 = arrEnd arr2 - start2
2018− newArrContents <-
2019− liftIO
2020− $ Unboxed.newAlignedPinnedBytes
2021− (len1 + len2)
2022− (alignment (undefined :: a))
2011+ newArrContents <- liftIO $ Unboxed.newPinnedBytes (len1 + len2)
20232012 let len = len1 + len2
20242013 newArr = Array newArrContents 0 len len
20252014 putSliceUnsafe arr1 start1 newArr 0 len1
core/src/Streamly/Internal/Data/Fold.hs+4−4
@@ -310,10 +310,10 @@ import Data.Bits (shiftL, shiftR, (.|.), (.&.))
310310import Data.Either (isLeft, isRight, fromLeft, fromRight)
311311import Data.Int (Int64)
312312import Data.Word (Word32)
313−import Foreign.Storable (peek, sizeOf)
313+import Foreign.Storable (Storable, peek)
314314import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
315315import Streamly.Internal.Data.Pipe.Type (Pipe (..), PipeState(..))
316−import Streamly.Internal.Data.Unboxed (Unbox)
316+import Streamly.Internal.Data.Unboxed (Unbox, sizeOf)
317317import Streamly.Internal.Data.Unfold.Type (Unfold(..))
318318import Streamly.Internal.Data.Tuple.Strict (Tuple'(..), Tuple3'(..))
319319import Streamly.Internal.Data.Stream.Type (Stream)
@@ -1684,7 +1684,7 @@ data SplitOnSeqState acc a rb rh w ck =
16841684--
16851685-- /Pre-release/
16861686{-# INLINE takeEndBySeq #-}
1687−takeEndBySeq :: forall m a b. (MonadIO m, Unbox a, Enum a, Eq a) =>
1687+takeEndBySeq :: forall m a b. (MonadIO m, Storable a, Unbox a, Enum a, Eq a) =>
16881688 Array.Array a
16891689 -> Fold m a b
16901690 -> Fold m a b
@@ -1820,7 +1820,7 @@ takeEndBySeq patArr (Fold fstep finitial fextract) =
18201820-- /Pre-release/
18211821--
18221822{-# INLINE takeEndBySeq_ #-}
1823−takeEndBySeq_ :: forall m a b. (MonadIO m, Unbox a, Enum a, Eq a) =>
1823+takeEndBySeq_ :: forall m a b. (MonadIO m, Storable a, Unbox a, Enum a, Eq a) =>
18241824 Array.Array a
18251825 -> Fold m a b
18261826 -> Fold m a b
core/src/Streamly/Internal/Data/Ring/Unboxed.hs+2−2
@@ -561,7 +561,7 @@ data Tuple4' a b c d = Tuple4' !a !b !c !d deriving Show
561561-- a))@ action depends on when it is executed. It does not capture the sanpshot
562562-- of the ring at a particular time.
563563{-# INLINE slidingWindowWith #-}
564−slidingWindowWith :: forall m a b. (MonadIO m, Unbox a)
564+slidingWindowWith :: forall m a b. (MonadIO m, Storable a, Unbox a)
565565 => Int -> Fold m ((a, Maybe a), m (Array a)) b -> Fold m a b
566566slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
567567
@@ -615,6 +615,6 @@ slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
615615-- there is no old element.
616616--
617617{-# INLINE slidingWindow #-}
618−slidingWindow :: forall m a b. (MonadIO m, Unbox a)
618+slidingWindow :: forall m a b. (MonadIO m, Storable a, Unbox a)
619619 => Int -> Fold m (a, Maybe a) b -> Fold m a b
620620slidingWindow n f = slidingWindowWith n (lmap fst f)
core/src/Streamly/Internal/Data/Stream/Eliminate.hs+2−1
@@ -78,6 +78,7 @@ where
7878#include "inline.hs"
7979
8080import Control.Monad.IO.Class (MonadIO(..))
81+import Foreign.Storable (Storable)
8182import Streamly.Internal.Data.Parser (Parser (..), ParseError (..))
8283import Streamly.Internal.Data.Unboxed (Unbox)
8384
@@ -290,7 +291,7 @@ isPrefixOf m1 m2 = D.isPrefixOf (toStreamD m1) (toStreamD m2)
290291-- /Requires 'Storable' constraint/
291292--
292293{-# INLINE isInfixOf #-}
293−isInfixOf :: (MonadIO m, Eq a, Enum a, Unbox a)
294+isInfixOf :: (MonadIO m, Eq a, Enum a, Storable a, Unbox a)
294295 => Stream m a -> Stream m a -> m Bool
295296isInfixOf infx stream = do
296297 arr <- fold Array.write infx
core/src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+4−4
@@ -154,7 +154,7 @@ import Control.Monad.IO.Class (MonadIO(..))
154154import Data.Bits (shiftR, shiftL, (.|.), (.&.))
155155import Data.Functor.Identity ( Identity )
156156import Data.Word (Word32)
157−import Foreign.Storable (peek, sizeOf)
157+import Foreign.Storable (Storable, peek)
158158import Fusion.Plugin.Types (Fuse(..))
159159import GHC.Types (SPEC(..))
160160
@@ -165,7 +165,7 @@ import Streamly.Internal.Data.Parser (ParseError(..))
165165import Streamly.Internal.Data.Refold.Type (Refold(..))
166166import Streamly.Internal.Data.SVar.Type (adaptState)
167167import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
168−import Streamly.Internal.Data.Unboxed (Unbox)
168+import Streamly.Internal.Data.Unboxed (Unbox, sizeOf)
169169import Streamly.Internal.Data.Unfold.Type (Unfold(..))
170170
171171import qualified Streamly.Internal.Data.Array.Type as A
@@ -1900,7 +1900,7 @@ data SplitOnSeqState rb rh ck w fs s b x =
19001900
19011901{-# INLINE_NORMAL splitOnSeq #-}
19021902splitOnSeq
1903− :: forall m a b. (MonadIO m, Unbox a, Enum a, Eq a)
1903+ :: forall m a b. (MonadIO m, Storable a, Unbox a, Enum a, Eq a)
19041904 => Array a
19051905 -> Fold m a b
19061906 -> Stream m a
@@ -2213,7 +2213,7 @@ data SplitOnSuffixSeqState rb rh ck w fs s b x =
22132213
22142214{-# INLINE_NORMAL splitOnSuffixSeq #-}
22152215splitOnSuffixSeq
2216− :: forall m a b. (MonadIO m, Unbox a, Enum a, Eq a)
2216+ :: forall m a b. (MonadIO m, Storable a, Unbox a, Enum a, Eq a)
22172217 => Bool
22182218 -> Array a
22192219 -> Fold m a b
core/src/Streamly/Internal/Data/Unboxed.hs+78−72
@@ -6,10 +6,8 @@
66
77module Streamly.Internal.Data.Unboxed
88 ( Unbox(..)
9− , alignment
109 , peekWith
1110 , pokeWith
12− , sizeOf
1311 , MutableByteArray(..)
1412 , castContents
1513 , touch
@@ -17,6 +15,7 @@ module Streamly.Internal.Data.Unboxed
1715 , pin
1816 , unpin
1917 , newUnpinnedBytes
18+ , newPinnedBytes
2019 , newAlignedPinnedBytes
2120 , nil
2221
@@ -40,7 +39,6 @@ module Streamly.Internal.Data.Unboxed
4039 ) where
4140
4241#include "MachDeps.h"
43−
4442#include "ArrayMacros.h"
4543
4644import Control.Monad (void, when)
@@ -51,7 +49,6 @@ import Data.Functor.Identity (Identity(..))
5149import Data.Kind (Type)
5250import Data.Proxy (Proxy (..))
5351import Foreign.Ptr (IntPtr(..), WordPtr(..))
54−import Foreign.Storable (Storable(..))
5552import GHC.Base (IO(..))
5653import GHC.Fingerprint.Type (Fingerprint(..))
5754import GHC.Int (Int16(..), Int32(..), Int64(..), Int8(..))
@@ -115,6 +112,16 @@ newUnpinnedBytes (I# nbytes) = IO $ \s ->
115112 let c = MutableByteArray mbarr#
116113 in (# s', c #)
117114
115+{-# INLINE newPinnedBytes #-}
116+newPinnedBytes :: Int -> IO (MutableByteArray a)
117+newPinnedBytes nbytes | nbytes < 0 =
118+ errorWithoutStackTrace "newPinnedBytes: size must be >= 0"
119+newPinnedBytes (I# nbytes) = IO $ \s ->
120+ case newPinnedByteArray# nbytes s of
121+ (# s', mbarr# #) ->
122+ let c = MutableByteArray mbarr#
123+ in (# s', c #)
124+
118125{-# INLINE newAlignedPinnedBytes #-}
119126newAlignedPinnedBytes :: Int -> Int -> IO (MutableByteArray a)
120127newAlignedPinnedBytes nbytes _align | nbytes < 0 =
@@ -175,7 +182,6 @@ unpin arr@(MutableByteArray marr#) =
175182-- The Unbox type class
176183--------------------------------------------------------------------------------
177184
178−-- XXX Remove dependency on Storable
179185-- XXX Use Proxy type in sizeOf method.
180186-- XXX generate error if the size is < 1
181187-- XXX Remove the phantom parameter from MutableByteArray?
@@ -208,9 +214,6 @@ unpin arr@(MutableByteArray marr#) =
208214-- anymore, see
209215-- https://lemire.me/blog/2012/05/31/data-alignment-for-speed-myth-or-reality/
210216--
211−-- We have to keep the instances compatible with Storable as we depend on it for
212−-- size and alignment. We can possibly write tests for checking compatibility
213−-- with Storable.
214217
215218-- The main goal of the Unbox type class is to be used in arrays. Invariants
216219-- for the sizeOf value required for use in arrays:
@@ -230,16 +233,6 @@ unpin arr@(MutableByteArray marr#) =
230233-- boxed type from the mutable byte array. The write operation 'pokeByteIndex'
231234-- writes the boxed type to the mutable byte array.
232235--
233−-- This type class depends on the 'Storable' for 'sizeOf' and 'alignment'
234−-- operations. While 'Storable' supplies the ability to serialize a type to a
235−-- 'Ptr' type, 'Unbox' augments it by supplying the ability to serialize to a
236−-- mutable byte array. The advantage of 'Unbox' over 'Storable' is that we can
237−-- use unpinned memory with 'Unbox'.
238−--
239−-- Note: Use the @QuantifiedConstraints@ language extension so that you can
240−-- just use a single 'Unbox' constraint in your code rather than using both
241−-- 'Storable' and 'Unbox'.
242−--
243236-- Here is an example, to write an instance for this type class.
244237--
245238-- >>> :{
@@ -249,30 +242,11 @@ unpin arr@(MutableByteArray marr#) =
249242-- }
250243-- :}
251244--
252−-- Note you can leave peek and poke undefined in 'Storable' if you are not
253−-- using the Storable instance, Unbox does not need these operations.
254−--
255−-- >>> import Foreign.Ptr (plusPtr, castPtr)
256−-- >>> import Foreign.Storable (Storable(..))
257−-- >>> :{
258−-- instance Storable Object where
259−-- sizeOf _ = 16
260−-- alignment _ = 8
261−-- peek ptr = do
262−-- let p = castPtr ptr
263−-- x0 <- peek p
264−-- x1 <- peek (p `plusPtr` 8)
265−-- return $ Object x0 x1
266−-- poke ptr (Object x0 x1) = do
267−-- let p = castPtr ptr
268−-- poke p x0
269−-- poke (p `plusPtr` 8) x1
270−-- :}
271−--
272245-- >>> import Streamly.Data.Array (Unbox(..))
273246-- >>> import Streamly.Internal.Data.Unboxed (castContents)
274247-- >>> :{
275248-- instance Unbox Object where
249+-- sizeOf _ = 16
276250-- peekByteIndex arr i = do
277251-- let p = castContents arr
278252-- x0 <- peekByteIndex p i
@@ -284,7 +258,9 @@ unpin arr@(MutableByteArray marr#) =
284258-- pokeByteIndex p (i + 8) x1
285259-- :}
286260--
287−class Storable a => Unbox a where
261+class Unbox a where
262+ -- | Get the size.
263+ sizeOf :: a -> Int
288264 -- | Read an element of type "a" from a MutableByteArray given the byte
289265 -- index.
290266 --
@@ -298,7 +274,7 @@ class Storable a => Unbox a where
298274 -- of the array, the caller must not assume that.
299275 pokeByteIndex :: MutableByteArray a -> Int -> a -> IO ()
300276
301−#define DERIVE_UNBOXED(_type, _constructor, _readArray, _writeArray) \
277+#define DERIVE_UNBOXED(_type, _constructor, _readArray, _writeArray, _sizeOf) \
302278instance Unbox _type where { \
303279; {-# INLINE peekByteIndex #-} \
304280; peekByteIndex (MutableByteArray mbarr) (I# n) = IO $ \s -> \
@@ -307,14 +283,18 @@ instance Unbox _type where { \
307283; {-# INLINE pokeByteIndex #-} \
308284; pokeByteIndex (MutableByteArray mbarr) (I# n) (_constructor val) = \
309285 IO $ \s -> (# _writeArray mbarr n val s, () #) \
286+; {-# INLINE sizeOf #-} \
287+; sizeOf _ = _sizeOf \
310288}
311289
312−#define DERIVE_WRAPPED_UNBOX(_constraint, _type, _constructor) \
313−instance _constraint Unbox _type where \
314−; {-# INLINE peekByteIndex #-} \
315−; peekByteIndex arr i = _constructor <$> peekByteIndex (castContents arr) i \
316−; {-# INLINE pokeByteIndex #-} \
317−; pokeByteIndex arr i (_constructor a) = pokeByteIndex (castContents arr) i a
290+#define DERIVE_WRAPPED_UNBOX(_constraint, _type, _constructor, _innerType) \
291+instance _constraint Unbox _type where \
292+; {-# INLINE peekByteIndex #-} \
293+; peekByteIndex arr i = _constructor <$> peekByteIndex (castContents arr) i \
294+; {-# INLINE pokeByteIndex #-} \
295+; pokeByteIndex arr i (_constructor a) = pokeByteIndex (castContents arr) i a \
296+; {-# INLINE sizeOf #-} \
297+; sizeOf _ = SIZE_OF(_innerType)
318298
319299#define DERIVE_BINARY_UNBOX(_constraint, _type, _constructor, _innerType) \
320300instance _constraint Unbox _type where { \
@@ -329,100 +309,117 @@ instance _constraint Unbox _type where { \
329309 let contents = castContents arr :: MutableByteArray _innerType \
330310 in pokeByteIndex contents i p1 >> \
331311 pokeByteIndex contents (i + SIZE_OF(_innerType)) p2 \
312+; {-# INLINE sizeOf #-} \
313+; sizeOf _ = 2 * SIZE_OF(_innerType) \
332314}
333315
334316DERIVE_UNBOXED( Char
335317 , C#
336318 , readWord8ArrayAsWideChar#
337− , writeWord8ArrayAsWideChar#)
319+ , writeWord8ArrayAsWideChar#
320+ , SIZEOF_HSCHAR)
338321
339322DERIVE_UNBOXED( Int8
340323 , I8#
341324 , readInt8Array#
342− , writeInt8Array#)
325+ , writeInt8Array#
326+ , 1)
343327
344328DERIVE_UNBOXED( Int16
345329 , I16#
346330 , readWord8ArrayAsInt16#
347− , writeWord8ArrayAsInt16#)
331+ , writeWord8ArrayAsInt16#
332+ , 2)
348333
349334DERIVE_UNBOXED( Int32
350335 , I32#
351336 , readWord8ArrayAsInt32#
352− , writeWord8ArrayAsInt32#)
337+ , writeWord8ArrayAsInt32#
338+ , 4)
353339
354340DERIVE_UNBOXED( Int
355341 , I#
356342 , readWord8ArrayAsInt#
357− , writeWord8ArrayAsInt#)
343+ , writeWord8ArrayAsInt#
344+ , SIZEOF_HSINT)
358345
359346DERIVE_UNBOXED( Int64
360347 , I64#
361348 , readWord8ArrayAsInt64#
362− , writeWord8ArrayAsInt64#)
349+ , writeWord8ArrayAsInt64#
350+ , 8)
363351
364352DERIVE_UNBOXED( Word
365353 , W#
366354 , readWord8ArrayAsWord#
367− , writeWord8ArrayAsWord#)
355+ , writeWord8ArrayAsWord#
356+ , SIZEOF_HSWORD)
368357
369358DERIVE_UNBOXED( Word8
370359 , W8#
371360 , readWord8Array#
372− , writeWord8Array#)
361+ , writeWord8Array#
362+ , 1)
373363
374364DERIVE_UNBOXED( Word16
375365 , W16#
376366 , readWord8ArrayAsWord16#
377− , writeWord8ArrayAsWord16#)
367+ , writeWord8ArrayAsWord16#
368+ , 2)
378369
379370DERIVE_UNBOXED( Word32
380371 , W32#
381372 , readWord8ArrayAsWord32#
382− , writeWord8ArrayAsWord32#)
373+ , writeWord8ArrayAsWord32#
374+ , 4)
383375
384376DERIVE_UNBOXED( Word64
385377 , W64#
386378 , readWord8ArrayAsWord64#
387− , writeWord8ArrayAsWord64#)
379+ , writeWord8ArrayAsWord64#
380+ , 8)
388381
389382DERIVE_UNBOXED( Double
390383 , D#
391384 , readWord8ArrayAsDouble#
392− , writeWord8ArrayAsDouble#)
385+ , writeWord8ArrayAsDouble#
386+ , SIZEOF_HSDOUBLE)
393387
394388DERIVE_UNBOXED( Float
395389 , F#
396390 , readWord8ArrayAsFloat#
397− , writeWord8ArrayAsFloat#)
391+ , writeWord8ArrayAsFloat#
392+ , SIZEOF_HSFLOAT)
398393
399394DERIVE_UNBOXED( (StablePtr a)
400395 , StablePtr
401396 , readWord8ArrayAsStablePtr#
402− , writeWord8ArrayAsStablePtr#)
397+ , writeWord8ArrayAsStablePtr#
398+ , SIZEOF_HSSTABLEPTR)
403399
404400DERIVE_UNBOXED( (Ptr a)
405401 , Ptr
406402 , readWord8ArrayAsAddr#
407− , writeWord8ArrayAsAddr#)
403+ , writeWord8ArrayAsAddr#
404+ , SIZEOF_HSPTR)
408405
409406DERIVE_UNBOXED( (FunPtr a)
410407 , FunPtr
411408 , readWord8ArrayAsAddr#
412− , writeWord8ArrayAsAddr#)
409+ , writeWord8ArrayAsAddr#
410+ , SIZEOF_HSFUNPTR)
413411
414−DERIVE_WRAPPED_UNBOX(,IntPtr,IntPtr)
415−DERIVE_WRAPPED_UNBOX(,WordPtr,WordPtr)
416−DERIVE_WRAPPED_UNBOX(Unbox a =>,(Identity a),Identity)
412+DERIVE_WRAPPED_UNBOX(,IntPtr,IntPtr,Int)
413+DERIVE_WRAPPED_UNBOX(,WordPtr,WordPtr,Word)
414+DERIVE_WRAPPED_UNBOX(Unbox a =>,(Identity a),Identity,a)
417415#if MIN_VERSION_base(4,14,0)
418−DERIVE_WRAPPED_UNBOX(Unbox a =>,(Down a),Down)
416+DERIVE_WRAPPED_UNBOX(Unbox a =>,(Down a),Down,a)
419417#endif
420−DERIVE_WRAPPED_UNBOX(Unbox a =>,(Const a b),Const)
418+DERIVE_WRAPPED_UNBOX(Unbox a =>,(Const a b),Const,a)
421419DERIVE_BINARY_UNBOX(forall a. Unbox a =>,(Complex a),(:+),a)
422−DERIVE_BINARY_UNBOX(forall a. (Integral a, Unbox a) =>,(Ratio a),(:%),a)
420+DERIVE_BINARY_UNBOX(forall a. Unbox a =>,(Ratio a),(:%),a)
423421DERIVE_BINARY_UNBOX(,Fingerprint,Fingerprint,Word64)
424422
425−-- XXX This should have a size 1.
426423instance Unbox () where
427424
428425 {-# INLINE peekByteIndex #-}
@@ -431,6 +428,9 @@ instance Unbox () where
431428 {-# INLINE pokeByteIndex #-}
432429 pokeByteIndex _ _ _ = return ()
433430
431+ {-# INLINE sizeOf #-}
432+ sizeOf _ = 1
433+
434434#if MIN_VERSION_base(4,15,0)
435435instance Unbox IoSubSystem where
436436
@@ -439,6 +439,9 @@ instance Unbox IoSubSystem where
439439
440440 {-# INLINE pokeByteIndex #-}
441441 pokeByteIndex arr i a = pokeByteIndex (castContents arr) i (fromEnum a)
442+
443+ {-# INLINE sizeOf #-}
444+ sizeOf = sizeOf . fromEnum
442445#endif
443446
444447instance Unbox Bool where
@@ -446,13 +449,16 @@ instance Unbox Bool where
446449 {-# INLINE peekByteIndex #-}
447450 peekByteIndex arr i = do
448451 res <- peekByteIndex (castContents arr) i
449− return $ res /= (0 :: Int32)
452+ return $ res /= (0 :: Int8)
450453
451454 {-# INLINE pokeByteIndex #-}
452455 pokeByteIndex arr i a =
453456 if a
454− then pokeByteIndex (castContents arr) i (1 :: Int32)
455− else pokeByteIndex (castContents arr) i (0 :: Int32)
457+ then pokeByteIndex (castContents arr) i (1 :: Int8)
458+ else pokeByteIndex (castContents arr) i (0 :: Int8)
459+
460+ {-# INLINE sizeOf #-}
461+ sizeOf _ = 1
456462
457463--------------------------------------------------------------------------------
458464-- Functions
src/Streamly/Internal/Data/Stream/IsStream/Common.hs+2−1
@@ -70,6 +70,7 @@ where
7070
7171import Control.Concurrent (threadDelay)
7272import Control.Monad.IO.Class (MonadIO(..))
73+import Foreign.Storable (Storable)
7374import Streamly.Internal.Control.Concurrent (MonadAsync)
7475import Streamly.Internal.Data.Array.Type (Array)
7576import Streamly.Internal.Data.Fold.Type (Fold (..))
@@ -679,7 +680,7 @@ foldManyPost f m = fromStreamD $ D.foldManyPost f (toStreamD m)
679680-- that we can search files in files for example.
680681{-# INLINE splitOnSeq #-}
681682splitOnSeq
682− :: (IsStream t, MonadIO m, Unbox a, Enum a, Eq a)
683+ :: (IsStream t, MonadIO m, Storable a, Unbox a, Enum a, Eq a)
683684 => Array a -> Fold m a b -> t m a -> t m b
684685splitOnSeq patt f m =
685686 IsStream.fromStreamD $ D.splitOnSeq patt f (IsStream.toStreamD m)
src/Streamly/Internal/Data/Stream/IsStream/Eliminate.hs+2−1
@@ -158,6 +158,7 @@ where
158158
159159import Control.Monad.IO.Class (MonadIO(..))
160160import Control.Monad.Trans.Class (MonadTrans(..))
161+import Foreign.Storable (Storable)
161162import Streamly.Internal.Control.Concurrent (MonadAsync)
162163import Streamly.Internal.Data.SVar (defState)
163164import Streamly.Internal.Data.Stream.IsStream.Common
@@ -849,7 +850,7 @@ isPrefixOf m1 m2 = D.isPrefixOf (toStreamD m1) (toStreamD m2)
849850-- /Requires 'Storable' constraint/
850851--
851852{-# INLINE isInfixOf #-}
852−isInfixOf :: (MonadIO m, Eq a, Enum a, Unbox a)
853+isInfixOf :: (MonadIO m, Eq a, Enum a, Storable a, Unbox a)
853854 => SerialT m a -> SerialT m a -> m Bool
854855isInfixOf infx stream = do
855856 arr <- fold A.write infx
src/Streamly/Internal/Data/Stream/IsStream/Reduce.hs+4−3
@@ -158,6 +158,7 @@ import Data.Kind (Type)
158158import Data.Map (Map)
159159import Data.Maybe (isNothing)
160160import Data.Proxy (Proxy(..))
161+import Foreign.Storable (Storable)
161162import Streamly.Internal.Control.Concurrent (MonadAsync)
162163import Streamly.Internal.Data.Fold.Type (Fold (..))
163164import Streamly.Internal.Data.IsMap (IsMap(..))
@@ -842,7 +843,7 @@ splitOnAny _subseq _f _m =
842843-- /Pre-release/
843844{-# INLINE splitBySeq #-}
844845splitBySeq
845− :: (IsStream t, MonadAsync m, Unbox a, Enum a, Eq a)
846+ :: (IsStream t, MonadAsync m, Storable a, Unbox a, Enum a, Eq a)
846847 => Array a -> Fold m a b -> t m a -> t m b
847848splitBySeq patt f m =
848849 intersperseM (fold f (A.read patt)) $ splitOnSeq patt f m
@@ -893,7 +894,7 @@ splitBySeq patt f m =
893894-- /Pre-release/
894895{-# INLINE splitOnSuffixSeq #-}
895896splitOnSuffixSeq
896− :: (IsStream t, MonadIO m, Unbox a, Enum a, Eq a)
897+ :: (IsStream t, MonadIO m, Storable a, Unbox a, Enum a, Eq a)
897898 => Array a -> Fold m a b -> t m a -> t m b
898899splitOnSuffixSeq patt f m =
899900 fromStreamD $ D.splitOnSuffixSeq False patt f (toStreamD m)
@@ -945,7 +946,7 @@ wordsOn _subseq _f _m =
945946-- /Pre-release/
946947{-# INLINE splitWithSuffixSeq #-}
947948splitWithSuffixSeq
948− :: (IsStream t, MonadIO m, Unbox a, Enum a, Eq a)
949+ :: (IsStream t, MonadIO m, Storable a, Unbox a, Enum a, Eq a)
949950 => Array a -> Fold m a b -> t m a -> t m b
950951splitWithSuffixSeq patt f m =
951952 fromStreamD $ D.splitOnSuffixSeq True patt f (toStreamD m)
test/Streamly/Test/Prelude/Serial.hs+2−1
@@ -20,6 +20,7 @@ import Data.List (sort, group, intercalate)
2020import Data.Maybe ( isJust, fromJust )
2121import Data.Word (Word8)
2222import Data.Semigroup (Sum(..), getSum)
23+import Foreign.Storable (Storable)
2324import Streamly.Internal.Data.Unboxed (Unbox)
2425import Test.Hspec.QuickCheck
2526import Test.QuickCheck
@@ -111,7 +112,7 @@ splitOnSuffixSeq = do
111112 $ IS.splitOnSuffixSeq (A.fromList pat) FL.toList (S.fromList xs)
112113
113114splitterProperties ::
114− forall a. (Arbitrary a, Eq a, Show a, Unbox a, Enum a)
115+ forall a. (Arbitrary a, Eq a, Show a, Storable a, Unbox a, Enum a)
115116 => a
116117 -> String
117118 -> Spec