@@ -84,6 +84,8 @@ module Streamly.Internal.Data.Array.Type
85 , pinnedWrite
85 , pinnedWrite
86 , unsafeMakePure
86 , unsafeMakePure
88 -- ** Streams of arrays
90 -- ** Streams of arrays
89 , chunksOf
91 , chunksOf
@@ -104,8 +106,9 @@ import Control.Exception (assert)
104import Control.Monad (replicateM)
106import Control.Monad (replicateM)
105import Control.Monad.IO.Class (MonadIO(..))
107import Control.Monad.IO.Class (MonadIO(..))
106import Data.Functor.Identity (Identity(..))
108import Data.Functor.Identity (Identity(..))
109+import Data.Int (Int8, Int16, Int32, Int64)
107import Data.Proxy (Proxy(..))
110import Data.Proxy (Proxy(..))
108−import Data.Word (Word8)
111+import Data.Word (Word8, Word16, Word32, Word64)
109import GHC.Base (build)
112import GHC.Base (build)
110import GHC.Exts (IsList, IsString(..), Addr#)
113import GHC.Exts (IsList, IsString(..), Addr#)
@@ -254,7 +257,10 @@ isPinned = MA.isPinned . unsafeThaw
254-- Construction
257-- Construction
255-------------------------------------------------------------------------------
258-------------------------------------------------------------------------------
257−-- Splice two immutable arrays creating a new array.
260+-- | Copy two immutable arrays into a new array. If you want to splice more
261+-- than two arrays then this operation would be highly inefficient because it
262+-- would make a copy on every splice operation, instead use the
263+-- 'fromArrayStreamK' operation to combine n immutable arrays.
258{-# INLINE splice #-}
264{-# INLINE splice #-}
259splice :: (MonadIO m, Unbox a) => Array a -> Array a -> m (Array a)
265splice :: (MonadIO m, Unbox a) => Array a -> Array a -> m (Array a)
260splice arr1 arr2 =
266splice arr1 arr2 =
@@ -687,12 +693,64 @@ instance Unbox a => IsList (Array a) where
687 {-# INLINE toList #-}
693 {-# INLINE toList #-}
688 toList = toList
694 toList = toList
690−-- XXX we are assuming that Unboxed equality means element equality. This may
696+-- | Byte compare two arrays. Compare the length of the arrays. If the length
691−-- or may not be correct? arrcmp is 40% faster compared to stream equality.
697+-- is equal, compare the lexicographical ordering of two underlying byte arrays
698+-- otherwise return the result of length comparison.
700+-- /Unsafe/: Note that the 'Unbox' instance of sum types with constructors of
701+-- different sizes may leave some memory uninitialized which can make byte
702+-- comparison unreliable.
705+{-# INLINE byteCmp #-}
706+byteCmp :: Array a -> Array a -> Ordering
708+ unsafeInlineIO $! unsafeThaw arr1 `MA.byteCmp` unsafeThaw arr2
710+-- | Byte equality of two arrays.
712+-- >>> byteEq arr1 arr2 = (==) EQ $ Array.byteCmp arr1 arr2
714+-- /Unsafe/: See 'byteCmp'.
715+{-# INLINE byteEq #-}
716+byteEq :: Array a -> Array a -> Bool
717+byteEq arr1 arr2 = (==) EQ $ byteCmp arr1 arr2
719+#define MK_EQ_INSTANCE(typ) \
720+instance {-# OVERLAPPING #-} Eq (Array typ) where { \
721+; {-# INLINE (==) #-} \
726+MK_EQ_INSTANCE(Word8)
727+MK_EQ_INSTANCE(Word16)
728+MK_EQ_INSTANCE(Word32)
729+MK_EQ_INSTANCE(Word64)
732+MK_EQ_INSTANCE(Int16)
733+MK_EQ_INSTANCE(Int32)
734+MK_EQ_INSTANCE(Int64)
736+-- | If the type allows a byte-by-byte comparison (see 'byteCmp') this instance
737+-- can be overlapped by a more specific instance that uses a byte comparison.
738+-- Byte comparison can be significantly faster.
742+-- >>> (==) = byteCmp
692−instance (Unbox a, Eq a) => Eq (Array a) where
744+instance {-# OVERLAPPABLE #-} (Unbox a, Eq a) => Eq (Array a) where
693 {-# INLINE (==) #-}
745 {-# INLINE (==) #-}
694 arr1 == arr2 =
746 arr1 == arr2 =
747+ -- Does unboxed byte equality mean element equality?
748+ -- XXX This is incorrect for sum types, as we may have some
749+ -- uninitialized memory in that case. If we always initialize the
750+ -- unused memory to zero we can use this.
751+ -- Byte comparison is 40% faster compared to stream equality.
695− (==) EQ $ unsafeInlineIO $! unsafeThaw arr1 `MA.cmp` unsafeThaw arr2
752+ -- (==) EQ $ unsafeInlineIO $! unsafeThaw arr1 `MA.cmp` unsafeThaw arr2
753+ (toStreamD arr1 :: Stream Identity a) == toStreamD arr2
697instance (Unbox a, Ord a) => Ord (Array a) where
755instance (Unbox a, Ord a) => Ord (Array a) where
698 {-# INLINE compare #-}
756 {-# INLINE compare #-}