当前更容易实现的经典示例conduit
是处理来自上游的输入结束。例如,如果你想折叠一个值列表并将结果绑定到管道中,如果没有pipes
在pipes
.
事实上,这正是即将推出的pipes-parse
库所要解决的问题。它Maybe
在上面设计了一个协议,pipes
然后定义了方便的函数,用于从上游绘制尊重该协议的输入。
例如,您有一个onlyK
函数,它接受一个管道并将所有输出包装在Just
其中,然后以 a 结束Nothing
:
onlyK :: (Monad m, Proxy p) => (q -> p a' a b' b m r) -> (q -> p a' a b' (Maybe b) m r)
您还具有该justK
函数,该函数定义了一个函子,Maybe
从不知道的管道到知道的管道,以Maybe
实现向后兼容性
justK :: (Monad m, ListT p) => (q -> p x a x b m r) -> (q -> p x (Maybe a) x (Maybe b) m r)
justK idT = idT
justK (p1 >-> p2) = justK p1 >-> justK p2
然后,一旦你有了一个Producer
尊重该协议的协议,你就可以使用各种各样的解析器来Nothing
为你抽象检查。最简单的是draw
:
draw :: (Monad m, Proxy p) => Consumer (ParseP a p) (Maybe a) m a
如果上游输入不足,它会检索类型的值a
或在代理转换器中失败。ParseP
您也可以一次取多个值:
drawN :: (Monad m, Proxy p) => Int -> Consumer (ParseP a p) (Maybe a) m [a]
drawN n = replicateM n draw -- except the actual implementation is faster
...以及其他几个不错的功能。用户实际上根本不需要直接与输入信号的结尾进行交互。
通常当人们要求处理输入结束时,他们真正想要的是解析,这就是为什么pipes-parse
将输入结束问题作为解析的子集。