Pipes Tutorial: ListT example

Viewed 348

I'm trying to make sense of one of the examples presented at the pipes tutorial concerning ListT:

import Pipes
import qualified Pipes.Prelude as P

input :: Producer String IO ()
input = P.stdinLn >-> P.takeWhile (/= "quit")

name :: ListT IO String
name = do
    firstName <- Select input
    lastName  <- Select input
    return (firstName ++ " " ++ lastName)

If the example above is run, we get output like the following:

>>> runEffect $ every name >-> P.stdoutLn
Daniel<Enter>
Fischer<Enter>
Daniel Fischer
Wagner<Enter>
Daniel Wagner
quit<Enter>
Donald<Enter>
Stewart<Enter>
Donald Stewart
Duck<Enter>
Donald Duck
quit<Enter>
quit<Enter>
>>> 

It seems that:

  1. When you run this (on ghci), the first name you input will get bound and only the second will change. I would expect that both producers (defined by Select input) will take turns (maybe non-deterministically) at reading the input.
  2. Entering quit one time will allow to re-bind the first name. Again, I fail to see why firstName will get bound to the first value entered by the user.
  3. Entering quit twice in a row will terminate the program. However, I would expect that quit only has to be entered twice to quit the program (possibly alternating with other input).

I'm missing something fundamental about the way the example above works, but I cannot see what.

2 Answers
Related