Я работаю над программой, использующей реактивный банан , и мне интересно, как структурировать мои типы с помощью основные строительные блоки FRP.
Например, вот упрощенный пример из моей реальной программы: скажем, моя система состоит в основном из виджетов - в моей программе фрагментов текста, которые меняются со временем.
Я мог бы иметь
newtype Widget = Widget { widgetText :: Behavior String }
, но также мог бы иметь
newtype Widget = Widget { widgetText :: String }
и использовать Виджет поведения
, когда я хочу поговорить о поведении, изменяющемся во времени. Это, кажется, упрощает работу и означает, что я могу использовать операции Behavior
напрямую, вместо того, чтобы распаковывать и переупаковывать виджеты для этого.
С другой стороны, первое, похоже, избегает дублирования в коде, который фактически определяет виджеты, поскольку почти все виджеты меняются со временем, и я обнаружил, что определяю даже те немногие, которые этого не делают, с помощью Behavior
, поскольку это позволяет мне более согласованно комбинировать их с другими.
В качестве другого примера с обоими представлениями имеет смысл иметь экземпляр Monoid
(и я хочу, чтобы он был в моей программе), но реализация последнего кажется более естественной (поскольку это просто тривиальное поднятие моноида списка до нового типа).
(Моя настоящая программа использует Дискретное
, а не Поведение
, но я не думаю, что это актуально.)
Точно так же следует использовать Поведение (Координаты, Coord)
или (Behavior Coord, Behavior Coord)
для представления двухмерной точки? В этом случае первое кажется очевидным выбором; но когда это запись из пяти элементов, представляющая что-то вроде сущности в игре, выбор кажется менее очевидным.
По сути, все эти проблемы сводятся к следующему:
При использовании FRP, на каком уровне мне следует применить тип Behavior
?
(Тот же вопрос относится к Event
тоже, хотя и в меньшей степени.)