I found an interesting library in Haskell called Scrap Your Boilerplate based on a paper by Simon Peyton Jones which seems like an effective way to write code that can update large, deeply nested data structures in a functional programming language. It enables code like:
incS :: Float -> Salary -> Salary
incS k (S s) = S (s * (1+k))
increase :: Float -> Company -> Company
increase k = everywhere (mkT (incS k))
Which effectively increases the salary by a fixed proportion k for everyone in a potentially large and complex Company data structure.
Is there an equivalent library or approach to achieve the same kind of programming style in Clojure?
For example, how could I write the Clojure equivalent of the example used above:
(defn increase [company k]
(everywhere-in company (transform-map-values :salary #(* % (+ 1 k))))