Last active
August 29, 2015 13:56
-
-
Save markhibberd/9245149 to your computer and use it in GitHub Desktop.
lens in clojure
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
;; repl session | |
(use 'lens) | |
(defrecord Address [street city postcode]) | |
(defrecord Person [name age address]) | |
(defrecord User [uid username identity password]) | |
(def -postcode (mklens :postcode)) | |
(def -city (mklens :city)) | |
(def -street (mklens :street)) | |
(def -address (mklens :address)) | |
(def -age (mklens :age)) | |
(def -name (mklens :name)) | |
(def -uid (mklens :uid)) | |
(def -username (mklens :username)) | |
(def -identity (mklens :identity)) | |
(def -password (mklens :password)) | |
(-get -postcode home) | |
(-set -postcode home 500) | |
(-modify -postcode home #(+ 10 %)) | |
(-get (comp -address -postcode) mark) | |
(-set (comp -address -postcode) mark 500) | |
(-get (comp -identity -address -postcode) user) | |
(-set (comp -identity -address -postcode) user 500) | |
(-modify (comp -identity -address -postcode) user #(+ 10 %)) |
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
(ns lens) | |
(defprotocol Functor | |
(fmap [functor f] "fmap :: f a -> (a -> b) -> f b")) | |
;; data Id a = Id { runId :: a } | |
(defrecord Id [runId] | |
Functor | |
(fmap [functor f] | |
(Id. (f (:runId functor))))) | |
;; data Const x a = Const { runConst :: x } | |
(defrecord Const [runConst] | |
Functor | |
(fmap [functor f] | |
(Const. (:runConst functor)))) | |
;; get a value | |
(defn -get [lens a] | |
(:runConst ((lens (fn [z] (->Const z))) a))) | |
;; modify a value with f | |
(defn -modify [lens a f] | |
(:runId ((lens (fn [z] (->Id (f z)))) a))) | |
;; set a value with b | |
(defn -set [lens a b] (-modify lens a (fn [bb] b))) | |
;; build a lens from a get and set function | |
(defn lens [getter, setter] | |
(fn [b-fb] | |
(fn [a] | |
(fmap (b-fb (getter a)) | |
(fn [b] (setter a b)))))) | |
;;;;;; the actual lens functions, someone who can do macros should get rid of these in about 2 minutes | |
(defn mklens [func] | |
(lens | |
(fn [a] (func a)) | |
(fn [a b] (assoc-in a [func] b)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment