Theo đường ống mặc định được kéo dựa. Điều này là do các nhà điều hành >->
được thực hiện thông qua +>>
là nhà điều hành quan trọng bind
cho danh mục kéo của mình. Hiểu biết của tôi là điều này có nghĩa là nếu bạn có mã số như producer >-> consumer
, cơ thể của người tiêu dùng sẽ được gọi trước, sau đó khi dữ liệu đang chờ dữ liệu, nhà sản xuất sẽ được gọi.Làm thế nào để biến một ống kéo dựa vào một đẩy dựa?
Tôi đã nhìn thấy trong tài liệu hướng dẫn pipes
here mà bạn có thể sử dụng mã (reflect .)
từ Pipes.Core
để biến một ống dựa kéo vào một ống dựa push. Điều đó có nghĩa là thay vào đó (sửa tôi nếu tôi sai) trong đoạn mã trên producer >-> consumer
, nhà sản xuất được chạy đầu tiên, tạo ra một giá trị, sau đó người tiêu dùng cố gắng tiêu thụ. Điều đó có vẻ thực sự hữu ích và tôi muốn biết làm thế nào để làm điều đó.
Tôi cũng thấy trong các cuộc thảo luận here rằng không có đối tác dựa trên push để >->
vì nó rất dễ dàng để biến bất kỳ đường ống xung quanh (tôi giả định với phản ánh?), Nhưng tôi không thể thực sự con số làm thế nào để làm điều đó hoặc tìm bất kỳ ví dụ nào.
Dưới đây là một số mã tôi đã cố gắng:
stdin :: Producer String IO r
stdin = forever $ do
lift $ putStrLn "stdin"
str <- lift getLine
yield str
countLetters :: Consumer String IO r
countLetters = forever $ do
lift $ putStrLn "countLetters"
str <- await
lift . putStrLn . show . length $ str
-- this works in pull mode
runEffect (stdin >-> countLetters)
-- equivalent to above, works
runEffect ((\() -> stdin) +>> countLetters)
-- push based operator, doesn't do what I hoped
runEffect (stdin >>~ (\_ -> countLetters))
-- does not compile
runEffect (countLetters >>~ (\() -> stdin))