Channel Tutorial: ListT Example

I am trying to understand one of the examples presented in the tutorial regarding 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 above example is running, we get the output as shown below:

>>> 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

  • When you run this (on ghci), the name you enter will be bound, and only the second will change. I would expect both manufacturers (defined Select input) to be too (possibly non-deterministic) when reading input.
  • Entering quitonce will re-associate the name. Again, I do not understand why it firstNamewill be bound to the first value entered by the user.
  • quit . , quit , (, ).

- , , , .

+6
2

( GHCi), , , . , ( Select input) ( ) .

ListT . "-". , , .

, , . :

input' :: String -> Producer String IO ()
input' msg = 
    (forever $ do 
        liftIO $ putStr msg
        r <- liftIO $ getLine
        yield r
    ) >-> P.takeWhile (/= "quit")

name' :: ListT IO String
name' = do
    firstName <- Select input
    lastName  <- Select $ input' $ "Enter a last name for " ++ firstName ++ ": "
    return (firstName ++ " " ++ lastName)

quit . , , firstName , .

quit, , , . " ", , , .

quit . , , quit , (, ).

, , "" .

, , quit, " ". , , .

+9

@danidiaz , name, firstName, , lastName s.

, MonadZip Monad m => ListT m,

mzip :: Monad m => ListT m a -> ListT m b -> ListT m (a, b).

, name

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

.

As a nice option, you can use the MonadComprehensionsand extensions ParallelListComp. Using them, two versions namebecome

name  :: ListT IO String
name  = [ firstName ++ " " ++ lastName | firstName <- Select input
                                       , lastName  <- Select input ]

name' :: ListT IO String
name' = [ firstName ++ " " ++ lastName | firstName <- Select input
                                       | lastName  <- Select input ]
0
source

Source: https://habr.com/ru/post/1017275/


All Articles