Вот пример кода:
(deftype Deck52 [suits] :as this
DeckOfCards
(check-empty []
(Deck52. (apply hash-map
(apply concat (remove (-> nil?)
(for [[key val] suits]
(if (empty? val) nil [key val])))))))
(remove-card [suit card]
(assoc suits suit (remove #(= card %) (suit suits))))
(get-card [suit]
(let [suitd (suit suits)]
[(first suitd) (check-empty (Deck52. (assoc suits suit (rest suitd))))]))
(random-card []
(let [suitn (+ 1 (rand-int 4))]
(cond (= suitn 1) (get-card this :hearts)
(= suitn 2) (get-card this :diamonds)
(= suitn 3) (get-card this :clubs)
(= suitn 4) (get-card this :spades)))))
Я также разместил этот код в Gist здесь, если его легче читать: http://gist.github.com/307425 (никуда не денется).
Основной пример здесь check-empty
. Мне было очень трудно знать, где я должен и не должен нажимать «вернуться», и я до сих пор не знаю, правильно ли я это сделал. Это грозит пройти прямо с правой стороны экрана, но это способ отступа в режиме Clojure, и я предполагаю, что так и должно быть.
Итак, вопрос в том, когда пора помещать новую строку в код Clojure / Lisp? Я делаю это обряд?
ПРИМЕЧАНИЕ: я не могу обещать, что код, который я разместил, работает. Я проводил некоторые эксперименты, и некоторые вещи могли бы быть просто отстойными, если не сломаны.