Ведут ли себя защищенные каналы так же, как каналы, использующие ожидание?

Каналы — это очень элегантная и очень простая версия итерации. Вы можете очень легко написать конвейерный код, используя примитивы await и yield. Паоло Каприотти расширил концепцию каналов с помощью защищенных каналов, в котором используется несколько более сложный примитив tryAwait, который позволяет каналу выполнять некоторую финализацию, когда заканчивается входной поток.

Реализация защищенного канала переопределяет await с точки зрения tryAwait:

await = tryAwait >>= maybe discard return

У меня такой вопрос: если я напишу код, ориентированный на более простую реализацию Pipes (с использованием await и yield), используя тот же код, будет ли он вести себя так же, если я переключусь на реализацию защищенного канала? Другими словами, можно ли рассматривать защищенный конвейерный код как просто надмножество конвейерного кода с точки зрения поведения?


person Dan Burton    schedule 04.02.2012    source источник


Ответы (2)


Это Габриэль, разместивший Pipes. Я работал с Паоло, и у нас в работе есть более элегантная реализация, которая является еще более мощной и безопасной для типов, чем его первоначальное предложение. Краткий ответ на ваш вопрос заключается в том, что окончательная реализация представляет собой расширенный набор исходных каналов, и вы можете написать тот же код, что и раньше, с идентичным поведением и семантикой.

Я могу даже резюмировать это довольно просто здесь. Операторы Await и yield — это единственные способы, которыми канал может отказаться от управления, поэтому мы прикрепляем к каждому из них запасной вариант, если восходящий или нисходящий канал завершается. Резервный вариант навсегда понижает качество канала, и он больше не может повторять неудачное действие. Неудачное ожидание понижает рейтинг канала до производителя, а неудачный выход понижает канал до потребителя. Если производитель не выдает или потребитель не ожидает, они понижаются до базовой монады, которая больше не может дать сбой.

Потребители и производители теперь являются отдельными типами и не подвергаются воздействию. Они такие же, как тип конвейера, за исключением отсутствия конструктора Await или Yield. Это необходимо, по крайней мере, для типа производителя, поскольку для каналов не существует входного типа, который может запрещать операторы ожидания.

Операторы await и yield по умолчанию завершаются в качестве резервного поведения, что является тем же поведением, что и раньше. 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
person Gabriel Gonzalez    schedule 05.02.2012

Ответ положительный.

С текущей реализацией каналов в Hackage ожидающий канал завершается, как только завершается его восходящий поток. То же самое верно и для защищенных каналов, если вы используете функцию await. У вас просто есть возможность использовать tryAwait вместо этого, если вам нужно вести себя особым образом перед завершением.

Кроме того, «охраняемая труба» — это лишь временное название концепции, пока мы прорабатываем лучший способ интеграции их функциональности. Я не думаю, что они будут выпущены отдельно.

person Paolo Capriotti    schedule 05.02.2012