Повторно получить случайный элемент в clojure

Я возился с Clojure, в частности с веб-фреймворком Noir, и пытаюсь создать случайную сетку плиток.

Это, вероятно, довольно плохой код, но я учусь! :D

(def tiles [:stairs :stone :monster]) 

(defpage "/" []
     (common/layout
       [:div {:class "level"}
        (repeatedly 10 [:div {:class "row"}
          (repeatedly 10
            [:div {:class (str "tile " (name (rand-nth tiles)))}])])]))

Но этот код выдает исключение:

Wrong number of args (0) passed to: PersistentVector - (class clojure.lang.ArityException)

person Kristjan Oddsson    schedule 21.01.2014    source источник


Ответы (2)


repeatedly принимает функцию, а не тело, поэтому вам нужно обернуть тела в функции:

(repeatedly 10 (fn []
                 [:div
                 {:class "row"}
                 (repeatedly 10 (fn []
                                  [:div {:class (str "tile " (name (rand-nth tiles)))}]))]))
person ponzao    schedule 21.01.2014
comment
Ааа, мне не хватало [] при попытке использовать fn раньше. Должен сказать, что я надеялся, что Clojure/Noir справится с этим красивее :› Спасибо! - person Kristjan Oddsson; 21.01.2014
comment
@KristjanOddsson, нет проблем! Я на самом деле нахожу довольно приятным, что Clojure не пытается быть слишком умным здесь (как это обычно не бывает), вы просто передаете функции функциям. - person ponzao; 21.01.2014

Отвечать:

user=> (repeatedly 10 (fn [] [:div]))
([:div] [:div] [:div] [:div] [:div] [:div] [:div] [:div] [:div] [:div])


user=> (repeatedly 10 [:div])    
ArityException Wrong number of args (0) passed to: PersistentVector  clojure.lang.AFn.throwArity (AFn.java:437)


user=> (doc repeatedly)
-------------------------
clojure.core/repeatedly
([f] [n f])
  Takes a function of no args, presumably with side effects, and
  returns an infinite (or length n if supplied) lazy sequence of calls
  to it
nil
user=>
person llj098    schedule 21.01.2014