Можно ли выразить функциональное реактивное программирование (FRP) с помощью монад?

Я читал "Функциональное реактивное программирование" , и хотя я не использовал моноды на любом языке, я не могу помогите, но увидите их повсюду в дизайне FRP.

Этот вопрос отвечает, есть некоторые фантастические описания того, что такое функциональное реактивное программирование, и я не буду пытаться воспроизвести это здесь. В принципе, FRP создает отношения между значениями, которые меняются со временем.

Неужели это невозможно представить монадически? Инкапсулируйте код, для которого требуются значения, которые со временем изменяются в монаде, назовите его Signal, а затем используйте эти сигналы, как это делается (используя простоту Haskell для простоты).

do
  mx <- mouseX
  my <- mouseY
  wave <- currentTime >>= liftM sin
  -- do some stuff with these values

Или есть ли еще FRP, чем я понимаю? Существуют ли парадигмы, которые препятствуют использованию такого простого представления с использованием монад? Или это действительное (если возможно упрощенное) понимание того, как работает FRP?

Ответ 1

Поведение может быть выполнено с помощью операций монады. Ведь Behavior a семантически Time -> a, который Reader Time.

Также событиям, которые семантически [(Time, a)] могут быть указаны как минимум Applicative экземпляр, который будет напоминать структуру ZipList.

Тем не менее, даже они теоретически возможны и изящны, на практике их трудно реализовать. Вы можете проверить "Управление временем и пространством: понимание многих формулировок FRP" Эвана Чаплицки для получения дополнительной информации.

Например sodium имеют вид монадического связывания для Behaviors:

switch :: Behavior (Behavior a) -> Reactive (Behavior a)

но вместо работы в чистой категории мы работаем в категории Kleisli монады Reactive. Таким образом, мы можем сделать немного больше.

Одно упражнение, которое подчеркивает трудности, заключается в попытке реализовать ArrowApply для Automaton. SO предоставил спойлер