Guest User

Untitled

a guest
Nov 24th, 2017
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.83 KB | None | 0 0
  1. (ns bank.account
  2. (:require
  3. [clojure.spec.alpha :as s]))
  4.  
  5. (s/def ::fname string?)
  6. (s/def ::lname string?)
  7. (s/def ::cents integer?)
  8.  
  9. ;; It's currently valid to have a negative balance.
  10. ;; Could alternatively do something like (s/and ::cents (complement neg?))
  11. (s/def ::balance ::cents)
  12.  
  13. ;; maybe use an inst here?
  14. (s/def ::date-of-birth string?)
  15.  
  16. ;; The first name is optional, the others are required.
  17. (s/def ::account
  18. (s/keys :req [::lname ::balance ::date-of-birth]
  19. :opt [::fname]))
  20.  
  21. (s/fdef deposit
  22. :args (s/cat :account ::account, :quantity ::cents)
  23. :ret ::account)
  24.  
  25. ;; This is the implementation I would use regardless of whether I used spec or not.
  26. (defn deposit [account quantity]
  27. (update account ::balance + quantity))
  28.  
  29. (s/fdef withdraw-valid?
  30. :args (s/cat :account ::account, :quantity ::cents)
  31. :ret boolean?)
  32.  
  33. (defn withdraw-valid? [{::keys [balance] :as account} quantity]
  34. (>= balance quantity))
  35.  
  36. (s/fdef withdraw
  37. :args (s/cat :account ::account, :quantity ::cents)
  38. :ret ::account)
  39.  
  40. (defn withdraw [account quantity]
  41. (update account ::balance - quantity))
  42.  
  43. (comment
  44.  
  45. ;; Usage
  46. (def me #::{:lname "madstap"
  47. :balance 100
  48. :date-of-birth "01-01-17"})
  49.  
  50. (withdraw me 100) ;=> #:bank.account{,,, :balance 0 ,,,}
  51.  
  52. (deposit me 1000) ;=> ;=> #:bank.account{,,, :balance 1100 ,,,}
  53.  
  54. (withdraw-valid? me 1000) ;=> false
  55.  
  56. ;; Bonus: Generate random, valid bank accounts.
  57. ;; NB: Needs test.check as a dependency [org.clojure/test.check "0.10.0-alpha2"]
  58. (clojure.pprint/pprint (s/exercise ::account))
  59.  
  60. ([#:bank.account{:lname "", :balance -1, :date-of-birth "", :fname ""}
  61. #:bank.account{:lname "", :balance -1, :date-of-birth "", :fname ""}]
  62. [#:bank.account{:lname "", :balance 0, :date-of-birth "6", :fname ""}
  63. #:bank.account{:lname "", :balance 0, :date-of-birth "6", :fname ""}]
  64. ,,,)
  65. )
Add Comment
Please, Sign In to add comment