Clojure эквивалент Haskell "Лом вашего котла" (SYB)

Я нашел интересную библиотеку в Haskell под названием Scrap Your Boilerplate на основе статьи Саймона Пейтона Джонса, который кажется эффективным способом написания кода, который может обновлять большие, глубоко вложенные структуры данных на функциональном языке программирования. Он позволяет использовать код типа:

incS :: Float -> Salary -> Salary
incS k (S s) = S (s * (1+k))

increase :: Float -> Company -> Company
increase k = everywhere (mkT (incS k))

Что эффективно увеличивает зарплату с фиксированной долей k для всех в потенциально большой и сложной структуре данных компании.

Существует ли эквивалентная библиотека или подход для достижения такого же стиля программирования в Clojure?

Например, как я мог бы записать эквивалент Clojure примера, использованного выше:

(defn increase [company k]
  (everywhere-in company (transform-map-values :salary #(* % (+ 1 k))))

Ответ 1

Ближайшим к этому в Clojure является, вероятно, "in" -функция (связать, обновить, распаковать).

Эти функции позволяют делать глубоко вложенные, точные изменения в clojure. В Haskell нет эквивалента этих функций, потому что они сильно зависят от динамического ввода.

Ответ 2

Их не было рядом, когда этот вопрос был впервые задан, но я считаю, что transducers позволяет использовать аналогичный стиль программирования. В основном, в процессах, реализуемых с помощью преобразователей, реализуется определенный набор функций, которые могут использовать преобразователи для перемещения по любому процессу.