Haskell 用另一个bytestring拆分懒惰的bytestring

Haskell 用另一个bytestring拆分懒惰的bytestring,haskell,lazy-evaluation,bytestring,Haskell,Lazy Evaluation,Bytestring,如何用另一个bytestring(例如,“\r\n”)拆分一个lazybytestring?我正在寻找如下函数: BSL.ByteString -> BSL.ByteString -> [BSL.ByteString] 我知道breakSubstring,但该函数仅适用于严格的byteststring。我也看到了这一点,但解决方案是使用严格的bytestring。回答我自己的问题:我创建了一个将breakSubstring添加到数据.bytestring.Lazy(改编自严格版本)

如何用另一个bytestring(例如,
“\r\n”
)拆分一个lazybytestring?我正在寻找如下函数:

BSL.ByteString -> BSL.ByteString -> [BSL.ByteString]

我知道
breakSubstring
,但该函数仅适用于严格的byteststring。我也看到了这一点,但解决方案是使用严格的bytestring。

回答我自己的问题:我创建了一个将
breakSubstring
添加到
数据.bytestring.Lazy
(改编自严格版本)中的

在合并拉取请求之前,可以使用以下代码:

{-# LANGUAGE BangPatterns #-}

module Lib (breakSubstring) where

import Data.Bits (finiteBitSize, shiftL, (.|.), (.&.))
import Data.Word (Word32)
import Prelude

import qualified Data.ByteString.Lazy as BSL


breakSubstring
  :: BSL.ByteString
  -> BSL.ByteString
  -> (BSL.ByteString, BSL.ByteString)
breakSubstring pat =
  case lp of
    0 -> \src -> (BSL.empty, src)
    1 -> BSL.break (== BSL.head pat)
    _ -> if lp * 8 <= fromIntegral (finiteBitSize (0 :: Word))
             then shift
             else karpRabin
  where
    lp = BSL.length pat
    karpRabin :: BSL.ByteString -> (BSL.ByteString, BSL.ByteString)
    karpRabin src
        | BSL.length src < lp = (src, BSL.empty)
        | otherwise = search (rollingHash $ BSL.take lp src) lp
      where
        k           = 2891336453 :: Word32
        rollingHash = BSL.foldl' (\h b -> h * k + fromIntegral b) 0
        hp          = rollingHash pat
        m           = k ^ lp
        get = fromIntegral . BSL.index src
        search !hs !i
            | hp == hs && pat == BSL.take lp b = u
            | BSL.length src <= i              = (src, BSL.empty)
            | otherwise                        = search hs' (i + 1)
          where
            u@(_, b) = BSL.splitAt (i - lp) src
            hs' = hs * k +
                  get i -
                  m * get (i - lp)
    {-# INLINE karpRabin #-}

    shift :: BSL.ByteString -> (BSL.ByteString, BSL.ByteString)
    shift !src
        | BSL.length src < lp = (src, BSL.empty)
        | otherwise           = search (intoWord $ BSL.take lp src) lp
      where
        intoWord :: BSL.ByteString -> Word
        intoWord = BSL.foldl' (\w b -> (w `shiftL` 8) .|. fromIntegral b) 0
        wp   = intoWord pat
        mask = (1 `shiftL` fromIntegral (8 * lp)) - 1
        search !w !i
            | w == wp             = BSL.splitAt (i - lp) src
            | BSL.length src <= i = (src, BSL.empty)
            | otherwise           = search w' (i + 1)
          where
            b  = fromIntegral (BSL.index src i)
            w' = mask .&. ((w `shiftL` 8) .|. b)
    {-# INLINE shift #-}
{-#语言模式}
模块库(断开子字符串),其中
导入数据位(finiteBitSize、shiftL、(.|.)、(.&.)
导入数据。Word(Word32)
进口序曲
将限定数据.ByteString.Lazy导入为BSL
断开子串
::BSL.ByteString
->BSL.ByteString
->(BSL.ByteString,BSL.ByteString)
断续拍打=
案例lp
0->\src->(BSL.empty,src)
1->BSL.break(=BSL.head pat)
_->如果lp*8(BSL.ByteString,BSL.ByteString)
卡普拉宾
|BSL.length srch*k+来自积分b)0
hp=滚球手拍
m=k^lp
get=from积分。索引src
搜索!啊!!我
|hp==hs&&pat==BSL.take lp b=u
|BSL.length src(BSL.ByteString,BSL.ByteString)
轮班!src
|BSL.length srcWord
intoWord=BSL.foldl'(\w b->(w`shiftL`8)。|.from积分b)0
wp=单词pat
掩码=(1`shiftL`from积分(8*lp))-1
搜索!W我
|w==wp=BSL.splitAt(i-lp)src

|BSL.length src正在转换严格的bytestring,或复制
breakSubstring
的定义(它使用可用于惰性bytestring的
take
isPrefixOf
)合适的解决方案?@user2407038转换为严格的bytestring和从严格的bytestring不是一个选项。由于内存的使用,我目前正在使用一个严格的bytestring并尝试切换到一个懒惰的bytestring。该函数使用了大量的
unsafeX
函数,这些函数对lazy-bytestring不可用。也许我可以使用正常的函数。