Reputation: 57
going through the pipes tutorial led to toying with some examples:
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
but the above produces:
>>> f1 3 [1..10]
1
2
3
4
5
6
7
8
9
10
>>> f2 3 [1..10]
1
2
3
>>>
contrary to my expectation that f1 and f2 would produce the same result (namely the result of f2). the question is: why don't they?
Upvotes: 1
Views: 63
Reputation: 7444
For has the type signature of:
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'
You second parameter for your for
is:
(lift . putStrLn . show)
Which is has a type of b -> Proxy ...
, but does not yield anything downstream since yield
is absent. This means that P.take
and P.stdoutLn
never run. Since P.take
does not receive any values it does not ever shutdown the pipeline.
If you wanted to print the value with for
and yield downstream you could:
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
edit:
Here are some additional code samples based on f1
using for
:
f3 :: Show a => Int -> [a] -> IO ()
f3 n xs = runEffect $ for (each xs >-> P.take n) (lift . putStrLn . show)
f4 :: Show a => Int -> [a] -> IO ()
f4 n xs = runEffect $ each [1..10] >-> for (P.take n) (lift . putStrLn . show)
> f3 3 [1..10]
1
2
3
> f4 3 [1..10]
1
2
3
Upvotes: 4