![](/img/trans.png)
[英]Best practice for handling data types from 3rd party libraries in Haskell?
[英]Handling sum encoding in Streaming libraries
这个问题背后的动机是这种情况 - 我们有一个由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)) mr
。 那么,是否存在某种变换器函数可以在输入流上运行compress
,并输出Stream (Of (Either ByteString ByteString)) mr
类型的Stream (Of (Either ByteString ByteString)) mr
,其中两者都被压缩。
在我看来,我应该编写一个自定义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
生成器,但是我已经针对输入只是源而不是流的简单情况实现了它们。 非常感谢这个问题的帮助。
解决这些情况的一个常见技巧是将和的每个分支放在不同的monadic层(因此将有两个流层)分别操作每个层,然后单独使用它们或在单个层中重新连接它们。
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
我们这样做是为了能够使用separate
和unseparate
的功能。
实际的压缩功能是:
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
用于在最顶层下方的一元层上工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.