Operating in nested stream when hoist is too generic

Next Topic
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Operating in nested stream when hoist is too generic


I ran into an issue when trying to use `hoist` because of `forall` quantifier which won't work when the morphing function is specialized. Will appreciate pointers on how we can operate on the nested monad. The problem is described below.

Suppose we have nested stream - let us say we build `Sum` encoding from `Either` stream, and want to call a transformation function on both - let it be a ByteString stream with return of (). Then, we want to combine them back into Either stream after transformation. So, we have `toSum`, `separate`, `unseparate`, and `fromSum` to split, transform and then combine it together - the only problem is `transform` function is too specific for `hoist`, and so, `hoist` can't be used. I can't figure out how to modify the nested stream (without lens):

toSum :: Monad m
=> Stream (Of (Either BS.ByteString BS.ByteString)) m r
-> Stream (Sum (Of BS.ByteString) (Of BS.ByteString)) m r

fromSum :: Monad m 
        => Stream (Sum (Of BS.ByteString) (Of BS.ByteString)) m r 
        -> Stream (Of (Either BS.ByteString BS.ByteString)) m r

:: (MonadIO m,Monad m) => Stream (Of BS.ByteString) m () -> Stream (Of BS.ByteString) m ()

-- Function to transform both Either byte streams
:: (MonadIO m,Monad m)
-> Stream (Of (Either BS.ByteString BS.ByteString)) m ()
-> Stream (Of (Either BS.ByteString BS.ByteString)) m ()
. unseparate . hoist transform . transform . separate . toSum

I also cribbed a `transLift` function from a StackOverflow post, but it doesn't seem to work on nested stream when used in place of `hoist` above:
-- Function to operate on nested monad - no forall quantifier unlike hoist
:: (Monad m, Monad (t m), MonadTrans t) => (m a -> m b) -> t m a -> t m b
transLift f tma
= tma >>= lift . f . return

I have other ways to access nested stream (like laid out in `Streaming` docs). However, I am curious what is good way to solve above problem where we want to combine the stream back after transformation.