![](/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.