У вас есть два варианта:
- Сделайте ваши объекты изменчивыми, а затем просто используйте те же приемы, что и в Java.
- Сделайте их неизменными, затем отбросьте двусторонние зависимости.
Чтобы понять почему, рассмотрим следующее преобразование между (неизменяемыми) деревьями.
Оба они определены с каждым родительским узлом, содержащим список дочерних узлов, но дети не знают своего родителя :
a (a)
b (b)
c c
d --> (d)
e e
f f
g g
В частности, узел d
был клонирован с новым значением. Для этого нам также пришлось клонировать все родительские узлы (показано в скобках).
Если бы узлы содержали своего родителя, тогда c
необходимо было бы "обновить", чтобы отразить новый узел b
, а e, f, g
пришлось бы обновить, чтобы отразить новый узел a
. т.е. все дерево должно быть скопировано!
Удерживая отношения только в одном направлении от родителя к ребенку, становится возможным повторное использование c, e, f, g
в последующих версиях структуры. Это мощная оптимизация и ключ к написанию эффективных функциональных алгоритмов.