Подтвердить что ты не робот

Какая альтернатива монадам использовать IO в чисто функциональном программировании?

монады описываются как решение haskell для работы с IO. Мне было интересно, существуют ли другие способы работы с IO на чистом функциональном языке.

4b9b3361

Ответ 1

Какие альтернативы существуют в монадах для ввода-вывода на чистом функциональном языке?

Я знаю две альтернативы в литературе:

  • Одна из них - так называемая система линейного типа. Идея состоит в том, что значение линейного типа должно использоваться ровно один раз: вы не можете его игнорировать, и вы не можете использовать его дважды. С учетом этой идеи вы даете состоянию мира абстрактный тип (например, World), и вы делаете его линейным. Если я отмечаю линейные типы со звездой, то здесь приведены типы операций ввода-вывода:

    getChar :: World* -> (Char, World*)
    putChar :: Char -> World* -> World*
    

    и т.д. Компилятор организует, чтобы убедиться, что вы никогда не копируете мир, а затем он может организовать компиляцию кода, который обновляет мир на месте, что безопасно, потому что есть только одна копия.

    Уникальность, заданная на языке Clean, основана на линейности.

    Эта система имеет несколько преимуществ; в частности, он не обеспечивает полное упорядочение событий, которые делают монады. Он также стремится избегать "IO бина sin", который вы видите в Haskell, где все эффективные вычисления помещаются в монаду IO, и все они полностью упорядочены независимо от того, хотите ли вы получить общий порядок или нет.

  • Другая система, которую я знаю о монадах Preates и Clean и основана на идее, что интерактивная программа является функцией из (возможно бесконечной) последовательности запросов к (возможно бесконечной) последовательности ответов. Эта система, которая называлась "диалоги", была чистым адом для программирования. Никто не скучает по нему, и в этом нет ничего, чтобы рекомендовать его. Его недостатки хорошо перечислены в документе, введя монадическое в/в (императивное функциональное программирование) Вадлером и Пейтоном Джонсом. В этой статье также упоминается система ввода-вывода, основанная на продолжениях, которые были введены группой Yale Haskell, но которая была недолговечной.

Ответ 3

Если "чистый" означает "ссылочно прозрачный", т.е. что прикладная функция свободно взаимозаменяема с ее оцененным результатом (и поэтому вызов функции с теми же аргументами имеет один и тот же результат каждый раз), любое понятие of stateful IO в значительной степени исключается по определению.

Есть две грубые стратегии, о которых я знаю:

  • Пусть функция выполняет IO, но убедитесь, что ее нельзя вызвать дважды с помощью тех же самых аргументов; эта сторона ставит проблему, позволяя функциям быть тривиально "ссылочно прозрачными".

  • Рассматривайте всю программу как единую чистую функцию, принимающую "все входные данные" в качестве аргумента и возвращающую "весь полученный результат", причем обе представлены в виде ленивого потока, чтобы обеспечить интерактивность.

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

В Haskell IO - это тип монады, который автоматически передает последовательное состояние через код (аналогично функционально чистой State монаде), так что концептуально каждый вызов другой нечистой функции получает другое значение неявного "состояния внешнего мира".

Другой популярный подход, который я знаю, использует нечто вроде линейные типы с аналогичным концом; гарантируя, что нечистые функции никогда не получат одинаковые аргументы дважды, имея значения, которые нельзя копировать или дублировать, так что старые значения "состояния внешнего мира" не могут быть сохранены и повторно использованы.

Ответ 4

Императивное функциональное программирование от Peyton Jones и Wadler - обязательно прочитайте, если вы заинтересованы в функциональном IO. Другие подходы, которые они обсуждают, следующие:

  • Диалоги, которые представляют собой ленивые потоки ответов и запросов.

type Dialogue = [Response] -> [Request]

main :: Dialogue

  • Продолжения - каждая операция ввода-вывода принимает продолжение в качестве аргумента

  • Линейные типы - система типов ограничивает вас тем, что вы не можете копировать или уничтожать внешнее состояние, а это значит, что вы не можете дважды вызвать функцию с тем же состоянием.

Ответ 5

Уникальная типизация используется в Clean