Created
August 14, 2021 14:32
-
-
Save kbridge/3f6b0f22ea8a99b7be18c01a2e4a72d7 to your computer and use it in GitHub Desktop.
lens implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def p1 | |
{:name "Danny", | |
:address {:country "Finland", | |
:city "Helsinki"}}) | |
(defn lens [key] | |
(let [getter key | |
setter (fn [s a] (assoc s key a))] | |
(fn [fmap] | |
(fn [f] | |
(fn [s] | |
(fmap #(setter s %) | |
(f (getter s)))))))) | |
(defn fmap-const [f x] x) | |
(defn fmap-identity [f x] (f x)) | |
; modify --> 'set' in haskell | |
(defn view [lens s] (((lens fmap-const) identity) s)) | |
(defn over [lens f s] (((lens fmap-identity) (comp f identity)) s)) | |
(defn modify [lens s a] (over lens (fn [_] a) s)) | |
(def person-name (lens :name)) | |
(def person-address (lens :address)) | |
(def address-city (lens :city)) | |
; test 1 | |
(view person-address p1) | |
(view address-city (view person-address p1)) | |
; test 2 | |
(over person-name clojure.string/upper-case p1) | |
; test 3 | |
(modify person-name p1 "xxx") | |
;------------------------------------------------------------------------------- | |
(defn compose-lens [a b] | |
(fn [fmap] | |
(comp (a fmap) (b fmap)))) | |
(def person-address-city (compose-lens person-address address-city)) | |
; tests | |
(view person-address-city p1) | |
(over person-address-city clojure.string/upper-case p1) | |
(modify person-address-city p1 "Espoo") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment