К сожалению, объединение «события» и «поведения» в один «сигнал» объекта не работает так хорошо.
Большинство реализаций FRP на основе сигналов, которые я знаю, в конечном итоге создают дополнительный тип, похожий на «событие», в соответствии с
type Event a = Signal (Maybe a)
Итак, концепция событий не исчезает, и нет никакого реального упрощения. На самом деле, я бы сказал, что тип сигнала - это семантическое усложнение. Сигналы популярны только потому, что их проще реализовать.
Основным аргументом против сигналов является то, что они не могут представлять непрерывное поведение во времени, потому что они должны обслуживать отдельные события. В оригинальном видении Конала Эллиота поведение было простой непрерывной функцией времени
type Behavior a = Time -> a
-- = function that takes the current time as parameter and returns
-- the corresponding value of type a
Напротив, сигналы всегда всегда дискретизируются и обычно связаны с фиксированным временным шагом. (Возможно реализовать и события, и поведение поверх сигнала с переменным временным шагом, но это не очень хорошая абстракция.) Сравните это с потоком событий
type Event a = [(Time,a)]
-- list of pairs of the form (current time, corresponding event value)
, где отдельные события не обязательно происходят в регулярно распределенных временных интервалах.
Аргумент в пользу различия между поведением и событиями заключается в том, что их API совершенно разные. Суть в том, что у них разные виды продукции:
(Behavior a , Behavior b) = Behavior (a,b)
(Event a , Event b ) = Event (a :+: b)
На словах: пара поведений - это то же самое, что поведение пар, но пара событий - это то же самое, что и событие из любого компонента / канала. Другое дело, что есть две операции
(<*>) :: Behavior (a -> b) -> Behavior a -> Behavior b
apply :: Behavior (a -> b) -> Event a -> Event b
, которые имеют почти одинаковый тип, но совершенно другую семантику. (Первый обновляет результат при изменении первого аргумента, а второй - нет.)
Подводя итог: сигналы могут использоваться для реализации FRP и полезны для экспериментов с новыми методами реализации, но поведение и события являются лучшей абстракцией для людей, которые просто хотят использовать FRP.
(Полное раскрытие: я реализовал библиотеку FRP под названием реактивный-банан в Haskell.)