haskell - 处理流媒体库中的和编码

标签 haskell haskell-pipes haskell-streaming

这个问题背后的动机是这种情况 - 我们有一个由 Sum 编码表示的值流。让我们假设 Either ByteString ByteString 分别表示处于错误状态和良好状态的字节流。现在,我们有另一个可以压缩 ByteString 流的函数。是否可以在 Either ByteString ByteString 输入流上运行此函数,并压缩其中一个(不仅是 Right,还可以压缩 Left,以防 产生 >Left 而不是 Right)。下面是 compress 函数类型签名(我正在使用 Streaming 库):

compress ::  MonadIO m 
         =>  Int 
         -- ^ Compression level.
         -> Stream (Of ByteString) m r
         -> Stream (Of ByteString) m r 

我们的输入流的类型为Stream (Of (Either ByteString ByteString)) m r。那么,是否有某种转换器函数可以在输入流上运行 compress ,并输出 Stream (Of (Either ByteString ByteString)) m r 类型的流,其中两者都是压缩。

在我看来,我应该编写一个自定义的compress,让我们说eithercompress如下:

eitherCompress :: MonadIO m 
             =>  Int 
             -- ^ Compression level.
             -> Stream (Of (Either ByteString ByteString)) m r
             -> Stream (Of (Either ByteString ByteString)) m r 

这是正确的吗?如果是这种情况,那么使用 zstd 中的以下函数编写 eitherCompress 的好方法是什么?图书馆:

compress :: Int 
         -- ^ Compression level. Must be >= 1 and <= maxCLevel.
         -> IO Result    

我已经使用yield编写了stream生成器,但我已经在输入只是源而不是流的简单情况下实现了它们。非常感谢您对这个问题的帮助。

最佳答案

解决这些情况的常见技巧是将总和的每个分支放在不同的单子(monad)层中(因此将有两个流层)分别操作每个层,然后单独使用它们或将它们重新加入到单个层中层。

首先是两个辅助函数,使用mapsSum 之间进行转换仿函数的组成:

toSum :: Monad m 
      => Stream (Of (Either ByteString ByteString)) m r 
      -> Stream (Sum (Of ByteString) (Of ByteString)) m r
toSum = maps $ \(eitherBytes :> x) -> 
    case eitherBytes of
        Left bytes -> InL (bytes :> x)
        Right bytes -> InR (bytes :> x)

fromSum :: Monad m 
        => Stream (Sum (Of ByteString) (Of ByteString)) m r 
        -> Stream (Of (Either ByteString ByteString)) m r
fromSum = maps $ \eitherBytes ->
    case eitherBytes of
        InL (bytes :> x) -> Left bytes :> x
        InR (bytes :> x) -> Right bytes :> x

我们这样做是为了能够使用 separateunseparate功能。

实际的压缩函数是:

eitherCompress :: MonadIO m 
               => Int 
               -> Stream (Of (Either ByteString ByteString)) m r 
               -> Stream (Of (Either ByteString ByteString)) m r
eitherCompress level =
     fromSum . unseparate . hoist (compress level) . compress level . separate . toSum

hoist用于处理最顶层下面的一元层。

关于haskell - 处理流媒体库中的和编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49224990/

相关文章:

haskell - 将字节串流式传输为 WAI HTTP 服务器响应正文

haskell - 为什么 Streaming-bytestring 给我错误 "openBinaryFile: resource exhausted (Too many open files)"?

Haskell 递增一

string - 通过在 Haskell 中插入每个后缀来构建后缀树

haskell - 在 Haskell 中折叠生产者/解析器时的空间爆炸

haskell - 具有动态请求/响应类型的管道?

haskell - 理解 Haskell 中的求值顺序

haskell - 重写规则的干净方法

haskell - 如何使用 Conduit 保存文件?

haskell - 概括Haskell "Streaming"库的合并功能