Поведение в реактивном банане - PullRequest
12 голосов
/ 30 июня 2011

Извините, я только начинаю изучать реактивный банан и FRP.

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

Что означает Поведение и каковы варианты его использования?

Ответы [ 4 ]

11 голосов
/ 01 июля 2011

Я согласен с Анкуром, а не с Крисом: текстовое поле - это значение со временем, и поэтому естественно хочет быть поведением, а не событием.Крис объясняет менее естественный выбор события реализацией проблемами и, таким образом (если точно) неудачным артефактом реализации реактивного банана.Я бы предпочел, чтобы реализация была лучше, чем неестественно используемая парадигма.

Помимо семантического соответствия, прагматически очень полезно выбирать Behavior вместо Event.Затем вы можете, например, использовать операции Applicative (например, liftA2) для объединения изменяющегося во времени значения текстового поля с другими изменяющимися во времени значениями (поведениями).

7 голосов
/ 30 июня 2011

Семантически, у вас есть

Behavior a = Time -> a

То есть Behavior a - это значение типа a, которое изменяется во времени. В общем, вы ничего не знаете о , когда a Behavior a изменится, так что это оказывается довольно неудачным выбором для обновления текстового поля нажатием кнопки. Тем не менее, было бы легко получить поведение, которое выражает текущее значение числа в примере счетчика. Просто используйте stepper в потоке событий или, альтернативно, создайте его с нуля таким же образом, за исключением использования accumB вместо accumE.

Обычно вещи, которые вы подключаете к вводу и выводу, всегда будут Event с, поэтому Behavior используется внутри для промежуточных результатов.

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

bmem    <- button f [text := "Remember"]
memory  <- staticText f []

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

let currentVal = stepper 0 counter

Затем вы можете подключить события и использовать apply для чтения значения поведения каждый раз, когда нажимается кнопка «Запомнить», и создавать Событие с этой последовательностью значений.

emem <- event0 bmem command
let memoryE = apply (const <$> currentVal) emem

И, наконец, подключите это новое событие к выводу

sink memory [text :== ("", show <$> memoryE)]

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

Это помогает?

6 голосов
/ 04 июля 2011

Говорит автор библиотеки.: -)

Очевидно, Крис Смит может читать мысли, потому что он точно описывает то, что я думаю.: -)

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

К сожалению, поведение не сопровождается какой-либо информацией о том, когда оно изменится, оно «только для опроса».Теперь я мог бы попытаться реализовать различные умные схемы, которые минимизируют опрос и, таким образом, позволяют эффективно обновлять элементы графического интерфейса.(Конал делает нечто похожее в оригинальной статье .) Но я принял философию «без магии»: пользователь библиотеки сам будет отвечать за управление обновлениями через события.

Решение Iв настоящее время предполагается предоставить третий тип помимо Event и Behavior, а именно Reactive (имя, подлежащее изменению), который воплощает в себе качества обоих: концептуально это значение, которое изменяется во времени, ноэто также идет с событием, которое уведомляет об изменениях.Одной из возможных реализаций будет

type Reactive a = (a,Event a)

changes :: Reactive a -> Event a
changes (_, e) = e

value :: Reactive a -> Behavior a
value   (x, e) = stepper x e

Неудивительно, что именно этого типа ожидает sink.Это будет включено в будущую версию библиотеки реактивного банана.

РЕДАКТИРОВАТЬ: Я выпустил реактивный банан версия 0.4 , который включает в себя новый тип, который теперь называется Discrete.

5 голосов
/ 30 июня 2011

Как правило, поведение - это значение, которое меняется в течение определенного периода времени.Это непрерывное значение, где события являются дискретными значениями.В случае Поведения значение всегда присутствует.Например: текст в текстовом поле является поведением, так как текст может изменяться в течение определенного периода времени, но будет текущее значение, например, как нажатие клавиши в событии, так как вы не можете запросить нажатие клавиатуры для его «текущего»значение.

...