Предположим, у меня есть набор компонентов, помеченных A-Z ... Я начинаю с отправки каждому компоненту значения 1,0, и каждый компонент возвращает двойное значение (скажем, a_0, b_0, .., z_0). На следующей итерации я отправляю сумму (1.0 + a_0 + ... + z_0) каждому компоненту, чтобы получить 26 новых двойных чисел (a_1, ..., z_1) и новое значение (1.0 + a_0 + ... + z_0 +) ... + a_1 + ... + z_1). Расчет продолжается таким образом изо дня в день.
Проблема в том, что каждый компонент сам по себе рекурсивен и использует около 20 значений предыдущих дней. Таким образом, наиболее очевидная рекурсивная реализация становится запутанной, поскольку каждый независимый путь вычисления компонента имеет массивный избыточный рекурсивный вызов.
В моей текущей реализации я разделил компоненты на несколько агентов, которые отвечают за свое состояние и используют передачу сообщений для завершения расчета. Сейчас я нахожусь в положении, когда мне нужно внести изменения в мою модель, и я считаю, что эта реализация не является гибкой.
Моя новая идея состоит в том, чтобы использовать неизменяемый объект для хранения состояния компонента, в котором на каждой итерации я бы клонировал свой объект компонента и обновлял состояние, используя различающее объединение. т.е.
Component(oldcomponent, [Parameter1(22.0), Parameter14(10.0)])
будет иметь состояние
oldcomponent, но обновите параметры 1 и 14. Таким образом, каждый путь вычисления компонента будет легко читаться, так как большинство путей обновляют только несколько параметров. И в качестве бонуса я могу разделить вычисления на ряд функций, которые принимают список мутаций в качестве входных данных и выводят новый список мутаций.
Однако я чувствую, что эта проблема хорошо подходит для функционального языка, и я несколько отклоняюсь от функционального дизайна, что хорошо, но мне любопытно, как другие будут решать эту проблему?
Edit:
Я полагаю, что аспект различающего объединения не имеет смысла, когда я мог бы использовать запись с «синтаксисом» для ее передачи.