Skip to content

Instantly share code, notes, and snippets.

@mattdenner
Last active December 18, 2015 04:49
Show Gist options
  • Select an option

  • Save mattdenner/5728014 to your computer and use it in GitHub Desktop.

Select an option

Save mattdenner/5728014 to your computer and use it in GitHub Desktop.
This was my rewriting of "An exercise in Refactoring - Playing around with Monoids and Endomorphisms" (http://debasishg.blogspot.in/2013/03/an-exercise-in-refactoring-playing.html). There are probably ways of doing this better and I'd love to hear about them. Note: I found `clojure.core.reducers/monoid`
; Functions can be seen as endomorphisms, hence they are a monoid, which is available
; in the reducers library!
(use '[clojure.core.reducers :as reducers :only (monoid)])
(def FunctionMonoid
(reducers/monoid
comp ; append
(fn [] (fn [v] v)))) ; zero
; Here is a function that, given a boolean, returns another function that
; will either return the function f passed to it, or m-zero. The former happens
; when b is true, the latter when b is false.
(defn boolean->function [b] (if b (fn [f] f) (fn [_] (FunctionMonoid))) )
; Each key in the salary configuration maps to a function that should
; be applied, and there is a defined order in which they should be
; applied.
(def option->function
[
[:allowance (fn [b] (* b 1.2))]
[:bonus (fn [b] (* b 1.1))]
[:tax (fn [b] (* b 0.7))]
[:surcharge (fn [b] (* b 0.9))]
])
; Given a salary configuration, this function returns another function
; that will return a function to be applied for each setting, whether the
; setting is enabled or not.
(defn settings [sc]
(fn [[setting function]] ((boolean->function (setting sc)) function)))
; Here's the salary computation function that takes a map for the settings,
; and a basic salary value.
(defn computeSalary [sc basic]
(let [setting->function (settings sc)
functions (map setting->function option->function)
calculator (reduce FunctionMonoid functions)]
(calculator basic)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment