HORIZON HASKELLDocslts/ghc-9.14.x45dd5372026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · 45dd537 · 2026-10-11

Setup

0 declarations
Example6 expressions
:m:set -XFlexibleContexts:set -XMagicHashimport Data.Function ((&))import Data.Functor.Identity (Identity(..))import System.IO.Unsafe (unsafePerformIO)
Example2 expressions
import Streamly.Data.Array (Array)import Streamly.Data.Stream (Stream)
Example5 expressions
import qualified Streamly.Data.Array as Arrayimport qualified Streamly.Data.Fold as Foldimport qualified Streamly.Data.ParserK as ParserKimport qualified Streamly.Data.Stream as Streamimport qualified Streamly.Data.StreamK as StreamK

For APIs that have not been released yet.

Example2 expressions
import qualified Streamly.Internal.Data.Array as Arrayimport qualified Streamly.Internal.Data.Stream as Stream

Design Notes

0 declarations

To summarize:

  • Arrays are finite and fixed in size

  • provide O(1) access to elements

  • store only data and not functions

  • provide efficient IO interfacing

Foldable instance is not provided because the implementation would be much less efficient compared to folding via streams. Semigroup and Monoid instances should be used with care; concatenating arrays using binary operations can be highly inefficient. Instead, use Streamly.Internal.Data.Stream.Chunked.toArray to concatenate N arrays at once.

Each array is one pointer visible to the GC. Too many small arrays (e.g. single byte) are only as good as holding those elements in a Haskell list. However, small arrays can be compacted into large ones to reduce the overhead. To hold 32GB memory in 32k sized buffers we need 1 million arrays if we use one array for each chunk. This is still significant to add pressure to GC.

The Array Type

133 declarations
valuebreakAt :: Unbox a => Int -> Array a -> (Array a, Array a)
#

Create two slices of an array without copying the original array. The specified index i is the first index of the second slice.

valuebyteCmp :: Array a -> Array a -> Ordering
#

Byte compare two arrays. Compare the length of the arrays. If the length is equal, compare the lexicographical ordering of two underlying byte arrays otherwise return the result of length comparison.

Unsafe: Note that the Unbox instance of sum types with constructors of different sizes may leave some memory uninitialized which can make byte comparison unreliable.

Pre-release

valuebyteEq :: Array a -> Array a -> Bool
#

Byte equality of two arrays.

Example1 expression
byteEq arr1 arr2 = (==) EQ $ Array.byteCmp arr1 arr2

Unsafe: See byteCmp.

valuechunksEndBy
  1. :: (MonadIO m, Unbox a)
  2. => a -> Bool
  3. -> Stream m a
  4. -> Stream m (Array a)
#

Create arrays from the input stream using a predicate to find the end of the chunk. When the predicate matches, the chunk ends, the matching element is included in the chunk.

Definition:

Example1 expression
chunksEndBy p = Stream.foldMany (Fold.takeEndBy p Array.create)
valuechunksOf :: (MonadIO m, Unbox a) => Int -> Stream m a -> Stream m (Array a)
#

chunksOf n stream groups the elements in the input stream into arrays of n elements each.

Same as the following but may be more efficient:

Example1 expression
chunksOf n = Stream.foldMany (Array.createOf n)

Pre-release

valuecompactGE
  1. :: (MonadIO m, Unbox a)
  2. => Int
  3. -> Stream m (Array a)
  4. -> Stream m (Array a)
#

Deprecated. Please use compactMin instead.

compactBySize n stream coalesces adjacent arrays in the stream until the size becomes greater than or equal to n.

Example1 expression
compactBySize n = Stream.foldMany (Array.createCompactMin n)

Generates unpinned arrays irrespective of the pinning status of input arrays.

valuecompactMin
  1. :: (MonadIO m, Unbox a)
  2. => Int
  3. -> Stream m (Array a)
  4. -> Stream m (Array a)
#

compactBySize n stream coalesces adjacent arrays in the stream until the size becomes greater than or equal to n.

Example1 expression
compactBySize n = Stream.foldMany (Array.createCompactMin n)

Generates unpinned arrays irrespective of the pinning status of input arrays.

valueconcat :: (Monad m, Unbox a) => Stream m (Array a) -> Stream m a
#

Convert a stream of arrays into a stream of their elements.

Example1 expression
concat = Stream.unfoldEach Array.reader
valueconcatRev :: (Monad m, Unbox a) => Stream m (Array a) -> Stream m a
#

Convert a stream of arrays into a stream of their elements reversing the contents of each array before flattening.

Example1 expression
concatRev = Stream.unfoldEach Array.readerRev
valuecreate :: (MonadIO m, Unbox a) => Fold m a (Array a)
#

Fold the whole input to a single array.

Caution! Do not use this on infinite streams.

valuecreateCompactMin
  1. :: (MonadIO m, Unbox a)
  2. => Int
  3. -> Fold m (Array a) (Array a)
#

Fold createCompactMin n coalesces adjacent arrays in the input stream until the size becomes greater than or equal to n.

Generates unpinned arrays irrespective of the pinning status of input arrays.

valuecreateWith :: (MonadIO m, Unbox a) => Int -> Fold m a (Array a)
#

A version of "create" that let's you pass in the initial capacity of the array in terms of the number of elements.

Semantically createWith 10 and createWith 100 will behave in the same way. createWith 100 will be more performant though.

create = createWith elementCount

Pre-release

valuedropWhile :: Unbox a => (a -> Bool) -> Array a -> Array a
#

Strip elements which match the predicate, from the start of the array.

Pre-release

valuefCompactGE :: (MonadIO m, Unbox a) => Int -> Fold m (Array a) (Array a)
#

Deprecated. Please use createCompactMin instead.

Fold createCompactMin n coalesces adjacent arrays in the input stream until the size becomes greater than or equal to n.

Generates unpinned arrays irrespective of the pinning status of input arrays.

valuefromCString# :: MonadIO m => Addr# -> m (Array Word8)
#

Copy a null terminated immutable Addr# Word8 sequence into an array.

Unsafe: The caller is responsible for safe addressing.

Note that this is completely safe when reading from Haskell string literals because they are guaranteed to be NULL terminated:

Note, you can use lazy unsafePerformIO _only if_ the pointer is immutable.

Example1 expression
Array.toList $ unsafePerformIO $ Array.fromCString# "\1\2\3\0"#[1,2,3]
valuefromListN :: Unbox a => Int -> [a] -> Array a
#

Create an Array from the first N elements of a list. The array is allocated to size N, if the list terminates before N elements then the array may hold less than N elements.

valuefromListRev :: Unbox a => [a] -> Array a
#

Create an Array from a list in reverse order. The list must be of finite size.

Pre-release

valuefromListRevN :: Unbox a => Int -> [a] -> Array a
#

Create an Array from the first N elements of a list in reverse order. The array is allocated to size N, if the list terminates before N elements then the array may hold less than N elements.

Pre-release

valuefromPtrN :: MonadIO m => Int -> Ptr Word8 -> m (Array Word8)
#

fromPtrN len addr copies len bytes from addr into an array. The memory pointed by addr must be pinned or static.

Unsafe: The caller is responsible to ensure that the pointer passed is valid up to the given length.

valuefromPureStream :: Unbox a => Stream Identity a -> Array a
#

Convert a pure stream in Identity monad to an immutable array.

Same as the following but with better performance:

Example1 expression
fromPureStream = Array.fromList . runIdentity . Stream.toList
valuefromStream :: (MonadIO m, Unbox a) => Stream m a -> m (Array a)
#

Create an Array from a stream. This is useful when we want to create a single array from a stream of unknown size. writeN is at least twice as efficient when the size is already known.

Example1 expression
fromStream = Stream.fold Array.create

Note that if the input stream is too large memory allocation for the array may fail. When the stream size is not known, chunksOf followed by processing of indvidual arrays in the resulting stream should be preferred.

Pre-release

valuefromStreamN :: (MonadIO m, Unbox a) => Int -> Stream m a -> m (Array a)
#

Create an Array from the first N elements of a stream. The array is allocated to size N, if the stream terminates before N elements then the array may hold less than N elements.

Example1 expression
fromStreamN n = Stream.fold (Array.createOf n)

Pre-release

valuefromW16CString :: MonadIO m => Ptr Word8 -> m (Array Word16)
#

Copy a C string consisting of 16-bit wide chars and terminated by a 16-bit null char, into a Word16 array. The null character is not copied.

Useful for copying UTF16 strings on Windows.

valuefromW16CString# :: MonadIO m => Addr# -> m (Array Word16)
#

Copy a C string consisting of 16-bit wide chars and terminated by a 16-bit null char, into a Word16 array. The null character is not copied.

Useful for copying UTF16 strings on Windows.

valuegetIndexUnsafe :: Unbox a => Int -> Array a -> a
#

Deprecated. Please use unsafeGetIndex instead.

Return element at the specified index without checking the bounds.

valuelCompactGE
  1. :: (MonadIO m, Unbox a)
  2. => Int
  3. -> Fold m (Array a) ()
  4. -> Fold m (Array a) ()
#

Deprecated. Please use scanCompactMin instead.

Like compactBySizeGE but for transforming folds instead of stream.

Example1 expression
lCompactBySizeGE n = Fold.many (Array.createCompactMin n)

Generates unpinned arrays irrespective of the pinning status of input arrays.

valuelength :: Unbox a => Array a -> Int
#

O(1) Get the length of the array i.e. the number of elements in the array.

valuenil :: Array a
#

Deprecated. Please use empty instead.

valuenull :: Array a -> Bool
#
Example1 expression
null arr = Array.byteLength arr == 0

Note that this may be faster than checking Array.length as length calculation involves a division operation.

Pre-release

valuepin :: Array a -> IO (Array a)
#

Return a copy of the Array in pinned memory if unpinned, else return the original array.

valuereaderUnsafe :: (Monad m, Unbox a) => Unfold m (Array a) a
#

Deprecated. Please use unsafeReader instead.

Unfold an array into a stream, does not check the end of the array, the user is responsible for terminating the stream within the array bounds. For high performance application where the end condition can be determined by a terminating fold.

Written in the hope that it may be faster than "read", however, in the case for which this was written, "read" proves to be faster even though the core generated with unsafeRead looks simpler.

Pre-release

valuesplice :: MonadIO m => Array a -> Array a -> m (Array a)
#

Copy two immutable arrays into a new array. If you want to splice more than two arrays then this operation would be highly inefficient because it would make a copy on every splice operation, instead use the fromChunksK operation to combine n immutable arrays.

valuesplitAt :: Unbox a => Int -> Array a -> (Array a, Array a)
#

Deprecated. Please use breakAt instead.

Create two slices of an array without copying the original array. The specified index i is the first index of the second slice.

valueunpin :: Array a -> IO (Array a)
#

Return a copy of the Array in unpinned memory if pinned, else return the original array.

valueunsafeAsForeignPtr
  1. :: MonadIO m
  2. => Array a
  3. -> ForeignPtr a -> Int -> IO b
  4. -> m b
#

Use an Array a as ForeignPtr a.

Unsafe because of direct pointer operations. The user must ensure that they are writing within the legal bounds of the array.

Pre-release

valueunsafeCreateOf :: (MonadIO m, Unbox a) => Int -> Fold m a (Array a)
#

Like createOf but does not check the array bounds when writing. The fold driver must not call the step function more than n times otherwise it will corrupt the memory and crash. This function exists mainly because any conditional in the step function blocks fusion causing 10x performance slowdown.

valueunsafeFreeze :: MutArray a -> Array a
#

Makes an immutable array using the underlying memory of the mutable array.

Please make sure that there are no other references to the mutable array lying around, so that it is never used after freezing it using unsafeFreeze. If the underlying array is mutated, the immutable promise is lost.

Pre-release

valueunsafeGetIndexIO :: Unbox a => Int -> Array a -> IO a
#

Return element at the specified index without checking the bounds.

Unsafe because it does not check the bounds of the array.

valueunsafeIndexIO :: Unbox a => Int -> Array a -> IO a
#

Deprecated. Please use unsafeGetIndexIO instead.

Return element at the specified index without checking the bounds.

Unsafe because it does not check the bounds of the array.

valueunsafeMakePure :: Monad m => Fold IO a b -> Fold m a b
#

Fold "step" has a dependency on "initial", and each step is dependent on the previous invocation of step due to state passing, finally extract depends on the result of step, therefore, as long as the fold is driven in the correct order the operations would be correctly ordered. We need to ensure that we strictly evaluate the previous step completely before the next step.

To not share the same array we need to make sure that the result of "initial" is not shared. Existential type ensures that it does not get shared across different folds. However, if we invoke "initial" multiple times for the same fold, there is a possiblity of sharing the two because the compiler would consider it as a pure value. One such example is the chunksOf combinator, or using an array creation fold with foldMany combinator. Is there a proper way in GHC to tell it to not share a pure expression in a particular case?

For this reason array creation folds have a MonadIO constraint. Pure folds could be unsafe and dangerous. This is dangerous especially when used with foldMany like operations.

Example1 expression
unsafePureWrite = Array.unsafeMakePure Array.create
valueunsafePinnedAsPtr :: MonadIO m => Array a -> (Ptr a -> Int -> IO b) -> m b
#

Use an Array a as Ptr a.

See unsafePinnedAsPtr in the Mutable array module for more details.

Unsafe

  1. The accessor must not access the array beyond the specified length.

  2. The accessor must not mutate the array.

Pre-release

valueunsafeReader :: (Monad m, Unbox a) => Unfold m (Array a) a
#

Unfold an array into a stream, does not check the end of the array, the user is responsible for terminating the stream within the array bounds. For high performance application where the end condition can be determined by a terminating fold.

Written in the hope that it may be faster than "read", however, in the case for which this was written, "read" proves to be faster even though the core generated with unsafeRead looks simpler.

Pre-release

valueunsafeSliceOffLen
  1. :: Unbox a
  2. => Int

    starting index

  3. -> Int

    length of the slice

  4. -> Array a
  5. -> Array a
#

O(1) Slice an array in constant time.

Caution: The bounds of the slice are not checked.

Unsafe

Pre-release

valueunsafeThaw :: Array a -> MutArray a
#

Makes a mutable array using the underlying memory of the immutable array.

Please make sure that there are no other references to the immutable array lying around, so that it is never used after thawing it using unsafeThaw. If the resulting array is mutated, any references to the older immutable array are mutated as well.

Pre-release

datadata Array a
#
Instances20IsList, Eq, Ord, Read, Show, IsString, …
  • Unbox a => IsList (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Int16)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Int32)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Int64)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Int8)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Char)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Int)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Word16)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Word32)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Word64)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Eq (Array Word8)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • (Unbox a, Eq a) => Eq (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type

    If the type allows a byte-by-byte comparison this instance can be overlapped by a more specific instance that uses byteCmp. Byte comparison can be significantly faster.

  • (Unbox a, Ord a) => Ord (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • (Unbox a, Read a, Show a) => Read (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • (Show a, Unbox a) => Show (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • a ~ Char => IsString (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Unbox a => Semigroup (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type

    This should not be used for combining many or N arrays as it would copy the two arrays everytime to a new array. For coalescing multiple arrays use fromChunksK instead.

  • Unbox a => Monoid (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type
  • Serialize (Array a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Serialize.Type
  • type Item (Array a) = aDefined in streamly-core-0.3.1 · Streamly.Internal.Data.Array.Type

Construction

1 declaration

Random Access

2 declarations
valueindexReader :: (Monad m, Unbox a) => Stream m Int -> Unfold m (Array a) a
#

Given a stream of array indices, read the elements on those indices from the supplied Array. An exception is thrown if an index is out of bounds.

This is the most general operation. We can implement other operations in terms of this:

read =
     let u = lmap (arr -> (0, length arr - 1)) Unfold.enumerateFromTo
      in Unfold.lmap f (indexReader arr)

readRev =
     let i = length arr - 1
      in Unfold.lmap f (indexReaderFromThenTo i (i - 1) 0)

Pre-release

valueindexReaderFromThenTo :: Unfold m (Int, Int, Int, Array a) a
#

Unfolds (from, then, to, array) generating a finite stream whose first element is the array value from the index from and the successive elements are from the indices in increments of then up to to. Index enumeration can occur downwards or upwards depending on whether then comes before or after from.

getIndicesFromThenTo =
    let f (from, next, to, arr) =
            (Stream.enumerateFromThenTo from next to, arr)
     in Unfold.lmap f getIndices

Unimplemented

Search

3 declarations
valuebinarySearch :: a -> Array a -> Maybe Int
#

Given a sorted array, perform a binary search to find the given element. Returns the index of the element if found.

Unimplemented

Casting

5 declarations
valuecast :: Unbox b => Array a -> Maybe (Array b)
#

Cast an array having elements of type a into an array having elements of type b. The length of the array should be a multiple of the size of the target element otherwise Nothing is returned.

valueunsafeCast :: Array a -> Array b
#

Cast an array having elements of type a into an array having elements of type b. The array size must be a multiple of the size of type b otherwise accessing the last element of the array may result into a crash or a random value.

Pre-release

valueasCStringUnsafe :: Array a -> (CString -> IO b) -> IO b
#

Convert an array of any element type into a null terminated CString Ptr. The array is copied to pinned memory.

Unsafe

O(n) Time: (creates a copy of the array)

Pre-release

valueasCWString :: Array a -> (CWString -> IO b) -> IO b
#

Convert an array of any element type into a null terminated CWString Ptr. The array is copied to pinned memory.

Unsafe

O(n) Time: (creates a copy of the array)

Pre-release

Subarrays

2 declarations
valuesplitterFromLen
  1. :: (Monad m, Unbox a)
  2. => Int

    from index

  3. -> Int

    length of the slice

  4. -> Unfold m (Array a) (Array a)
#

Generate a stream of slices of specified length from an array, starting from the supplied array index. The last slice may be shorter than the requested length.

Pre-release/

Streaming Operations

1 declaration

Folding

3 declarations

Stream of Arrays

8 declarations
valueconcatSepBy :: (Monad m, Unbox a) => a -> Stream m (Array a) -> Stream m a
#

Insert the given element between arrays and flatten.

Example1 expression
concatSepBy x = Stream.unfoldEachSepBy x Array.reader
valueconcatEndBy :: (Monad m, Unbox a) => a -> Stream m (Array a) -> Stream m a
#

Insert the given element after each array and flatten. This is similar to unlines.

Example1 expression
concatEndBy x = Stream.unfoldEachEndBy x Array.reader
valuecompactMax
  1. :: (MonadIO m, Unbox a)
  2. => Int
  3. -> Stream m (Array a)
  4. -> Stream m (Array a)
#

compactMax n coalesces adjacent arrays in the input stream only if the combined size would be less than or equal to n.

Generates unpinned arrays irrespective of the pinning status of input arrays.

Parsing Stream of Arrays

8 declarations
valuefoldChunks
  1. :: (MonadIO m, Unbox a)
  2. => Fold m a b
  3. -> Stream m (Array a)
  4. -> m b
#

Fold a stream of arrays using a Fold. This is equivalent to the following:

Example1 expression
foldChunks f = Stream.fold f . Stream.unfoldEach Array.reader
valuefoldBreak
  1. :: (MonadIO m, Unbox a)
  2. => Fold m a b
  3. -> StreamK m (Array a)
  4. -> m (b, StreamK m (Array a))
#

Fold a stream of arrays using a Fold and return the remaining stream.

The following alternative to this function allows composing the fold using the parser Monad:

foldBreakStreamK f s =
      fmap (first (fromRight undefined))
    $ StreamK.parseBreakChunks (ParserK.adaptC (Parser.fromFold f)) s

We can compare perf and remove this one or define it in terms of that.

Serialization

4 declarations
valueserialize :: Serialize a => a -> Array Word8
#

Properties: 1. Identity: deserialize . serialize == id 2. Encoded equivalence: serialize a == serialize a

valueserialize' :: Serialize a => a -> Array Word8
#

Serialize a Haskell type to a pinned byte array. The array is allocated using pinned memory so that it can be used directly in OS APIs for writing to file or sending over the network.

Properties:

  1. Identity: deserialize . serialize' == id

  2. Encoded equivalence: serialize' a == serialize' a

Deprecated

19 declarations
valueslicerFromLen
  1. :: (Monad m, Unbox a)
  2. => Int

    from index

  3. -> Int

    length of the slice

  4. -> Unfold m (Array a) (Array a)
#

Deprecated. Please use splitterFromLen instead.

Generate a stream of slices of specified length from an array, starting from the supplied array index. The last slice may be shorter than the requested length.

Pre-release/

valuecastUnsafe :: Array a -> Array b
#

Deprecated. Please use unsafeCast instead.

Cast an array having elements of type a into an array having elements of type b. The array size must be a multiple of the size of type b otherwise accessing the last element of the array may result into a crash or a random value.

Pre-release

valuepinnedSerialize :: Serialize a => a -> Array Word8
#

Deprecated. Please use serialize' instead.

Serialize a Haskell type to a pinned byte array. The array is allocated using pinned memory so that it can be used directly in OS APIs for writing to file or sending over the network.

Properties:

  1. Identity: deserialize . serialize' == id

  2. Encoded equivalence: serialize' a == serialize' a

valueinterpose :: (Monad m, Unbox a) => a -> Stream m (Array a) -> Stream m a
#

Deprecated. Please use concatSepBy instead.

Insert the given element between arrays and flatten.

Example1 expression
concatSepBy x = Stream.unfoldEachSepBy x Array.reader
valueinterposeSuffix
  1. :: (Monad m, Unbox a)
  2. => a
  3. -> Stream m (Array a)
  4. -> Stream m a
#

Deprecated. Please use concatEndBy instead.

Insert the given element after each array and flatten. This is similar to unlines.

Example1 expression
concatEndBy x = Stream.unfoldEachEndBy x Array.reader
valueintercalateSuffix
  1. :: (Monad m, Unbox a)
  2. => Array a
  3. -> Stream m (Array a)
  4. -> Stream m a
#

Deprecated. Please use concatEndBySeq instead.

Insert the given array after each array and flatten.

Example1 expression
concatEndBySeq x = Stream.unfoldEachEndBySeq x Array.reader
valuecompactLE
  1. :: (MonadIO m, Unbox a)
  2. => Int
  3. -> Stream m (Array a)
  4. -> Stream m (Array a)
#

Deprecated. Please use compactMax instead.

compactMax n coalesces adjacent arrays in the input stream only if the combined size would be less than or equal to n.

Generates unpinned arrays irrespective of the pinning status of input arrays.

Deprecated. Please use compactSepByByte_ instead.

Split a stream of byte arrays on a given separator byte, dropping the separator and coalescing all the arrays between two separators into a single array.

valuefold :: (Monad m, Unbox a) => Fold m a b -> Array a -> m b
#

Deprecated. Please use foldM instead.

Fold an array using a Fold.

Pre-release

valuefoldBreakChunksK
  1. :: (MonadIO m, Unbox a)
  2. => Fold m a b
  3. -> StreamK m (Array a)
  4. -> m (b, StreamK m (Array a))
#

Deprecated. Please use foldBreak instead.

Fold a stream of arrays using a Fold and return the remaining stream.

The following alternative to this function allows composing the fold using the parser Monad:

foldBreakStreamK f s =
      fmap (first (fromRight undefined))
    $ StreamK.parseBreakChunks (ParserK.adaptC (Parser.fromFold f)) s

We can compare perf and remove this one or define it in terms of that.