Skip to content

Instantly share code, notes, and snippets.

@rafaellima
Last active September 27, 2022 14:52
Show Gist options
  • Save rafaellima/267c43fba7412f11e286a6576332b1b8 to your computer and use it in GitHub Desktop.
Save rafaellima/267c43fba7412f11e286a6576332b1b8 to your computer and use it in GitHub Desktop.
Money
(ns ch1.money)
(declare validate-same-currency)
(defrecord Currency [divisor sym desc])
(defrecord Money [amount ^Currency currency]
java.lang.Comparable
(compareTo [m1 m2]
(validate-same-currency m1 m2)
(compare (:amount m1) (:amount m2))))
(def currencies {:usd (->Currency 100 "USD" "US Dollars")
:eur (->Currency 100 "EUR" "Euro")})
(defn- validate-same-currency
[m1 m2]
(or (= (:currency m1) (:currency m2))
(throw
(ex-info "Currencies do not match."
{:m1 m1 :m2 m2}))))
(defn =$
([m1] true)
([m1 m2] (zero? (.compareTo m1 m2)))
([m1 m2 & monies]
(every? zero? (map #(.compareTo m1 %) (conj monies m2)))))
(defn +$
([m1] m1)
([m1 m2]
(validate-same-currency m1 m2)
(->Money (+ (:amount m1) (:amount m2)) (:currency m1)))
([m1 m2 & monies]
(reduce +$ m1 (conj monies m2))))
(defn *$ [m n] (->Money (* n (:amount m)) (:currency m)))
(defn make-money
([] (make-money 0))
([amount] (make-money amount :usd))
([amount currency] (->Money amount currency)))
(defn -$ [m1 m2 & monies] ,,,)
(defn allocate [m proportions] ,,,)
(def zero-dollars (make-money 0 :usd))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment