Łączenie przewodów z wieloma wejściami

Próbuję utworzyć kanał, który może wykorzystywać wiele strumieni wejściowych. Muszę być w stanie oczekiwać na jeden lub drugi strumień wejściowy bez określonej kolejności (np. Nie na przemian), czyniąc zip bezużytecznym. Nie ma tu nic równoległego ani niedeterministycznego: czekam na jeden lub drugi strumień. Chcę móc pisać kod podobny do następującego (gdzieawaitA iawaitB poczekaj odpowiednio na pierwszy lub drugi strumień wejściowy):

do
  _ <- awaitA
  x <- awaitA
  y <- awaitB
  yield (x,y)
  _ <- awaitB
  _ <- awaitB
  y' <- awaitB
  yield (x,y')

Najlepszym rozwiązaniem, jakie mam, jest uczynienie wewnętrznej monady innym przewodem, np.

foo :: Sink i1 (ConduitM i2 o m) ()

Co wtedy pozwala

awaitA = await
awaitB = lift await

I to głównie działa. Niestety, wydaje się, że bardzo trudno jest połączyć się z przewodem wewnętrznym, zanim przewód zewnętrzny zostanie w pełni podłączony. Pierwszą rzeczą, którą próbowałem, było:

fuseInner :: Monad m =>
                Conduit i2' m i2 -> 
                Sink i1 (ConduitM i2 o m) () -> 
                Sink i1 (ConduitM i2' o m) ()
fuseInner x = transPipe (x =$=)

Ale to nie działa, przynajmniej kiedyx jest stanowy od tego czasu(x =$=) jest uruchamiany wiele razy, skutecznie restartującx za każdym razem.

Czy jest jakiś sposób na napisanie fuseInner, poza włamaniem się do wewnętrznych elementów conduit (które wyglądałyby na dość niechlujne)? Czy jest jakiś lepszy sposób na obsługę wielu strumieni wejściowych? Czy jestem w drodze do daleko poza to, do czego został zaprojektowany kanał?

Dzięki!

questionAnswers(2)

yourAnswerToTheQuestion