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