从管道中了解 'leftover'

Understanding 'leftover' from conduit

为什么会出现下面的输出[]?

λ: >runConduitPure $ yieldMany [1..2] .| leftover 5 .| sinkList
[]

我天真地期望它 return:[1,2,5] 根据 leftover 的文档:

Provide a single piece of leftover input to be consumed by the next component in the current monadic binding.

我们必须区分Conduit>>=.|的组成。

对于 >>=,我们正在对共享公共输入和公共输出流的两个 Conduit 的操作进行排序。

使用 .|,我们将一个 Conduit 的输出流连接到另一个

的输入流。

leftover 函数将一个值推送到当前 Conduit 输入流的当前位置,使其可用于连接到同一输入流的其他 Conduit 操作( >>=)。它不会 yield 任何东西进入当前 Conduit 的输出流,这就是为什么 sinkList 在你的例子中产生空列表。

如果你想看到leftover的效果,你必须执行sinkList,它可以访问与leftover相同的输入流:

runConduitPure $ yieldMany [1..2] .| (leftover 5 >> sinkList)

这会产生 [5, 1, 2](不是 [1, 2, 5]),因为 leftover1 之前将 5 推入输入流,并且 2,已消耗

如果我们在leftover之前添加一个await

runConduitPure $ yieldMany [1..2] .| (await >> leftover 5 >> sinkList)

然后我们得到 [5, 2] 因为我们在执行 leftover.

之前消耗(并丢弃)1

我们也可以从我们的 leftover Conduityield,这会将一个值推入输出流以供另一个 Conduit 使用 [=15] =]:

runConduitPure $ yieldMany [1..2] .| myLeftoverConduit .| sinkList where
  myLeftoverConduit = do
    leftover 5
    l <- sinkList
    yield l
    yield [42]

产生 [[5, 1, 2], [42]] 因为我们 yielded sinkList (一个列表)的结果,然后 yielded [42] (也是一个列表) .然后下游 sinkList 列出这两个值。