Created
June 24, 2015 17:11
-
-
Save nathanmarz/7a6bbf80770d2a232f33 to your computer and use it in GitHub Desktop.
Practical example of Specter
This file contains 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 world | |
{:people [{:money 129827 :name "Alice Brown"} | |
{:money 100 :name "John Smith"} | |
{:money 6821212339 :name "Donald Trump"} | |
{:money 2870 :name "Charlie Johnson"} | |
{:money 8273821 :name "Charlie Rose"} | |
] | |
:bank {:funds 4782328748273}} | |
) | |
(defn transfer | |
"Note that this function works on *any* world structure. This handles | |
arbitrary many to many transfers of a fixed amount without overdrawing anyone" | |
[world from-path to-path amt] | |
(let [givers (select from-path world) | |
receivers (select to-path world) | |
total-receive (* amt (count givers)) | |
total-give (* amt (count receivers))] | |
(if (every? #(>= % total-give) givers) | |
(->> world | |
(update from-path #(- % total-give)) | |
(update to-path #(+ % total-receive)) | |
) | |
(throw (IllegalArgumentException. | |
"Insufficient funds")) | |
))) | |
(defn pay-fee [world] | |
(transfer world | |
[:people ALL :money] | |
[:bank :funds] | |
1) | |
) | |
(defn bank-give-dollar [world] | |
(transfer world | |
[:bank :funds] | |
[:people ALL :money] | |
1) | |
) | |
(defn pay-poor-fee [world] | |
(transfer world | |
[:people ALL :money #(< % 3000)] | |
[:bank :funds] | |
50) | |
) | |
(defn rich-people [world] | |
(select [:people | |
ALL | |
(selected? :money #(>= % 1000000000)) | |
:name] | |
world)) | |
(defn user [name] | |
(comp-paths :people | |
ALL | |
(selected? :name | |
#(= % name)))) | |
(defn transfer-users [world from to amt] | |
(transfer world | |
[(user from) :money] | |
[(user to) :money] | |
amt)) | |
(defn bank-loyal-bonus | |
"Bank gives $5000 to earliest three users" | |
[world] | |
(transfer world | |
[:bank :funds] | |
[:people (srange 0 3) ALL :money] | |
5000)) | |
(defn add-person [world person] | |
(setval [:people END] | |
[person] | |
world) | |
) | |
(defn bank-recent-charity-bonus | |
"Bank gives $1000 to most recent person with less than 5000 dollars" | |
[world] | |
(transfer world | |
[:bank :funds] | |
[:people | |
(filterer [:money #(< % 5000)]) | |
(selected? (view empty?) not) | |
LAST | |
:money] | |
1000)) | |
(defn mark-wealth-status [world] | |
(setval [:people | |
ALL | |
(if-path [:money #(>= % 100000)] | |
:rich | |
:not-so-rich)] | |
true | |
world)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment