Соединение трубопроводов с несколькими входами

,

Я пытаюсь создать канал, который может потреблять несколько входных потоков. Мне нужно иметь возможность ожидать одного или другого входного потока в произвольном порядке (например, без чередования), что делает бесполезным почтовый индекс. Здесь нет ничего параллельного или недетерминированного: я жду одного или другого потока. Я хочу быть в состоянии написать код, подобный следующему (гдеawaitA а такжеawaitB ждите на первом или втором входном потоке соответственно):

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

Лучшее решение, которое у меня есть, - это сделать внутреннюю монаду другим каналом, например,

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

Который затем позволяет

awaitA = await
awaitB = lift await

И это в основном работает. К сожалению, это, кажется, делает очень трудным плавкий переход к внутреннему каналу, прежде чем внешний канал будет полностью подключен. Первое, что я попробовал, было:

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

Но это не работает, по крайней мере, когдаx&nbsp;с учетом состояния(x =$=)&nbsp;запускается несколько раз, эффективно перезапускаяx&nbsp;каждый раз.

Есть ли способ написать fuseInner, если не взломать внутреннюю часть канала (похоже, это было бы довольно грязно)? Есть ли лучший способ для обработки нескольких входных потоков? Я просто далеко за пределами того, для чего был разработан трубопровод?

Спасибо!