通过pipes tutorial导致玩弄了一些例子:
import Pipes
import qualified Pipes.Prelude as P
f1 :: Show a => Int -> [a] -> IO ()
f1 n xs = runEffect $ (for (each xs) (lift . putStrLn . show))
>-> P.take n
>-> P.stdoutLn
f2 :: Show a => Int -> [a] -> IO ()
f2 n xs = runEffect $ each xs
>-> P.map show
>-> P.take n
>-> P.stdoutLn
但以上产生:
>>> f1 3 [1..10]
1
2
3
4
5
6
7
8
9
10
>>> f2 3 [1..10]
1
2
3
>>>
与我的预期相反,f1和f2会产生相同的结果(即f2的结果)。问题是:为什么不呢?
答案 0 :(得分:4)
For具有以下类型的签名:
for
:: Monad m =>
Proxy x' x b' b m a'
-> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'
for
的第二个参数是:
(lift . putStrLn . show)
哪个类型为b -> Proxy ...
,但由于yield
不存在,因此不会产生下游任何内容。这意味着P.take
和P.stdoutLn
永远不会运行。由于P.take
没有收到任何值,因此它不会关闭管道。
如果您想使用for
打印价值并向下游收益,您可以:
f1 :: Show a => Int -> [a] -> IO ()
f1 n xs = runEffect $ (for (each xs)
(\x -> (lift . putStrLn . show) x >> yield x))
>-> P.show
>-> P.take n
>-> P.stdoutLn
> f1 3 [1..10]
1
1
2
2
3
3
编辑:
以下是基于使用f1
的{{1}}的其他代码示例:
for