Skip to content

Instantly share code, notes, and snippets.

@cgrand
Created January 28, 2015 02:04
Show Gist options
  • Select an option

  • Save cgrand/bb2b34e0e6cbc73832bf to your computer and use it in GitHub Desktop.

Select an option

Save cgrand/bb2b34e0e6cbc73832bf to your computer and use it in GitHub Desktop.
Van Laarhoven lenses in Clojure
;; lenses in Clojure again, van Laarhoven-style this time
(defprotocol Lens
(through [lens x cont]))
(extend-protocol Lens
clojure.lang.Keyword
(through [k x cont]
(cont #(assoc x k %) (k x))))
(defn- return [_ v] v)
(defn fetch [x l]
(through l x return))
(defn putback [x l v]
(through l x (fn [g _] (g v))))
(defn update [x l f & args]
(through l x (fn [g v] (g (apply f v args)))))
(defn compose [l1 l2]
(reify Lens
(through [l1+l2 x f]
(through l1 x (fn [g1 v1] (through l2 v1 (fn [g2 v2] (f (comp g1 g2) v2))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment