Является ли FRP надлежащим способом реализации большинства "событийных" вещей?

В моем самом первом впечатлении от Haskell, этот язык может отлично справляться с "выполнением-результатом-результатом". Но я не могу найти, как реализовать "управляемые событиями" такие вещи, как игры или серверы HTTP/FTP/TCPSocket.

Этот вопрос получил ответ после того, как я прочитал несколько статей о FRP, включая Yampa и созданную им FPS-игру (Frag). Похоже, что FRP - хорошая модель для реализации "тяжелых" событий, таких как 3D-игра, но как насчет более сложных приложений, управляемых событиями, таких как HTTP-серверы или обычные графические программы для рабочего стола? Какие минусы появятся, если я использую FRP для реализации всех этих вещей?

Ответы

Ответ 1

FRP - очень общий метод и почти наверняка может быть использован для реализации всего, что обычно использует события. В классическом исполнении FRP одной из основных абстракций является событие. Разница в том, что вместо того, чтобы работать с событиями индивидуально с обратными вызовами, вы работаете с потоками событий.

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

На самом деле, у меня был хороший опыт использования FRP для того, что вы называете "легче": простые графические программы. Я использовал реактивный банан с помощью wxWidgets, чтобы написать очень простые маленькие графические программы. Я обнаружил, что полученный код будет намного проще, легче писать и читать легче, чем эквивалентный код на основе обратного вызова.

Reactive Banana также может использоваться для таких вещей, как музыка, поэтому он явно широко применим. Я не пробовал ничего, кроме программирования GUI с ним, но у других есть так, что это должно быть возможно.

Кроме того, вы должны проверить Elm, который является языком стиля ML для реализации веб-приложений с FRP. Он генерирует все, что вам нужно: HTML, CSS и JavaScript. Я считаю, что он даже обрабатывает связь с сервером. Я не пробовал, но выглядит очень хорошо.

Итак, люди явно используют FRP в самых разных областях, включая те, которые не являются "тяжелыми". Но это не значит, что вы должны использовать его везде!

Во-первых, можно получить непредсказуемое пространственное и временное поведение. Я знаю, что создатели Reactive Banana и Elm приложили немало усилий для их сокращения, но я подозреваю, что есть еще некоторый риск. Я знаю, что у меня было очень странное пространство, когда вы играли с Reactive Banana WX, так что, конечно же, что-то нужно искать. С FRP может быть труднее справиться с ними, чем с кодом события, с которым вы привыкли работать. Конечно, у меня были необъяснимые утечки памяти со стандартным JavaScript, поэтому код без FRP не застрахован от этого!

Еще одно соображение заключается в том, что FRP не может быть лучшей или четкой абстракцией для вашей конкретной задачи. Хотя это здорово для вещей, которые должны быть полностью реактивными, что относительно кода, который очень прост, как веб-сервер? (Я имею в виду, что простые, как и в разных запросах, вероятно, не слишком тесно взаимодействуют друг с другом.) Я полагаю, что возможно создание веб-фреймворка, который обрабатывал большое количество запросов с использованием модели программирования на основе FRP; Я просто не думаю, что это было бы оптимально.

Фактически, я понимаю, что система ввода-вывода GHC на самом деле уже управляется событиями под капотом, поэтому вы можете писать веб-серверы в стандартном стиле программирования и получать преимущества использования событий бесплатно. Таким образом, для кода веб-сервера более простая базовая абстракция может быть лучшим выбором. Я считаю, что существующие структуры, такие как Snap и Yesod, не используют стиль реактивного программирования, но оба они по-прежнему приятны в использовании.

Ответ 2

Вам не нужно использовать что-либо помимо "простого" Haskell для реализации игр, управляемых событиями. В настоящее время я пишу FPS с использованием Haskell со следующей (ОЧЕНЬ высокоуровневой) архитектурой:

uiMake :: IO ([UIEvent],UIState)
uiTick :: UIState -> [ApEvent] -> IO ([UIEvent],UIState)

apMake :: ([ApEvent],ApState)
apTick :: ApState -> [UIEvent] -> ([ApEvent],ApState)

-- UIState = The state of the UI
-- ApState = The state of the application (game)
-- UIEvent = Key presses, screen resolution changes etc.
-- ApEvent = Entity movements etc.

Он отлично работает. Нет необходимости в объективах, FRP или чем-то еще "экзотическом".