Можно ли в Conduit построить функцию (скажем zipC2), которая бы переворачивала следующие исходники:
series1 = yieldMany [2, 4, 6, 8, 16 :: Int]
series2 = yieldMany [1, 5, 6 :: Int]
в один, который будет производить следующие пары (показанные здесь в виде списка):
[(Nothing, Just 1), (Just 2, Just 1), (Just 4, Just 1), (Just 4, Just 5), (Just 6, Just 6), (Just 8, Just 6), (Just 16, Just 6)]
Он будет вызываться с помощью функции сравнения следующим образом:
runConduitPure ( zipC2 (<=) series1 series1 .| sinkList )
Раньше в предыдущих версиях была функция mergeSources
, которая делала что-то относительно похожее (правда, без эффекта памяти), но она исчезла в самой последней версии (1.3.1).
Пояснение о том, как работает функция. Идея состоит в том, чтобы взять 2 источника A (генерирующие значения a) и B. (генерация значений b).
Затем мы генерируем пары:
Если a ‹ b, мы сначала строим (просто a, ничего)
Если b ‹ a, это даст (ничего, просто b)
Если a == b, мы обновляем обе стороны и получаем (Just a, Just b)
Необновленное значение из источника не используется и используется для следующего раунда сравнений. Используются только обновленные значения.
Затем мы продолжаем обновлять пару в соответствии со значениями из A и B относительно друг друга.
Другими словами: мы обновляем левую часть пары, если a ‹ b, правую часть, если b ‹ a, или обе стороны, если a == b эм>. Любое неиспользованное значение сохраняется в памяти для следующего раунда сравнения.