问题
I need to compose a consumer and a pipe so that the output of the consumer would feed the input of the pipe.
I guess this could be solved with a combinator like this:
Consumer i m r -> (r -> Producer o m r') -> Pipe i o m r'
or this:
Consumer i m i' -> Pipe i' o m r -> Pipe i o m r
or a lifting function like the following:
Consumer i m r -> Pipe i o m r
or like this:
Consumer i m o -> Pipe i o m r
I tried doing consumer >~ pipe
without a success. So how to approach this?
回答1:
Something similar to your signature Consumer i m o -> Pipe i o m r
could be done like this:
{-# LANGUAGE RankNTypes #-}
import Pipes
foo :: Monad m => Consumer' i m o -> Pipe i o m ()
foo consumer = consumer >>= yield
I have used the Consumer'
polymorphic type synonym which, since it is not really closed "downstream", it can be used as a Pipe
that never actually yield
s. To make it yield the return value of the consumer, we simply use a monadic bind.
As for your Consumer i m r -> Pipe i o m r
signature, it's simply the identity using the polymorphic type synonym:
iden :: Monad m => Consumer' i m r -> Pipe i o m r
iden consumer = consumer
回答2:
For your first type signature, if your Consumer
and Producer
use the polymorphic type synonyms Consumer'
and Producer'
, then the combinator you want is (>>=)
:
(>>=) :: Pipe i o m r -> (r -> Pipe i o m r') -> Pipe i o m r'
A Consumer' i m r
will type-check as a Pipe i o m r
. Similarly, a Producer' o m r'
will type-check as a Pipe i o m r'
.
来源:https://stackoverflow.com/questions/24742367/running-a-consumer-inside-a-pipe