Ответ 1
Это Габриэль, который разместил Труба. Я работал с Паоло, и у нас есть более элегантная реализация в работах, которые еще более мощные и типичные, чем его первоначальное предложение. Короткий ответ на ваш вопрос заключается в том, что окончательная реализация представляет собой надмножество оригинальных труб, и вы можете написать тот же код, что и раньше, с одинаковым поведением и семантикой.
Я даже могу изложить его довольно просто здесь. Операторы "ожидание" и "доходность" - это единственные способы, с помощью которых труба может отказаться от контроля, поэтому мы присоединяем к каждому из них резервную ошибку, если заканчивается восходящий или нисходящий поток. Резервная версия постоянно отказывает трубку, и она больше не может повторять неудавшееся действие. Сбой ожидания не позволяет понизить канал до производителя, а неудавшаяся доходность понизит цену для потребителя. Если производитель не может уступить или потребитель не ждет, он будет понижен до базовой монады, которая больше не может терпеть неудачу.
Потребители и производители теперь являются отдельными типами, и они не подвергаются воздействию. Они такие же, как тип типа трубы, за исключением отсутствия конструктора Await или Yield. Это необходимо, по крайней мере, для типа производителя, так как нет типа ввода для труб, которые могут запрещать утверждения ожидания.
Ожидайте и выведите утверждения по умолчанию для завершения, как их поведение назад, что является тем же самым поведением, что и раньше. Ожидание и доходность будут классифицироваться для работы в странах с пониженным рейтингом, которые их поддерживают. Однако теперь вы можете по желанию предоставить свой собственный резерв, как только мы придумаем более сексуальное имя, чем tryAwait или tryYield.
Мне еще нужно проверить, что Pipes все еще образуют категорию с этим расширением, но это кажется очень вероятным. Он также 100% типов и использует типы для принудительного использования понижающего уровня, а не логического и проверенного инвариантом программиста.
Изменить: некоторый код функционирования, чтобы поднять аппетит (проверьте использование ветки "try" из репозитория github для использования расширения):
printer = forever $ await >>= lift . print
take' n = replicateM_ n $ await >>= yield
fromList' = mapM_ (yieldOr (lift $ putStrLn "Undelivered elements))
diagnose = forever $ do
x <- awaitOr (lift $ putStrLn "Await failed")
yieldOr (lift $ putStrLn "Yield failed") x
> runPipe $ printer <+< take' 3 <+< diagnose <+< fromList [1..10]
1
2
3
Yield failed
Undelivered elements
> runPipe $ printer <+< take' 10 <+< diagnose <+< fromList [1..3]
1
2
3
Await failed