如何使用lazy seq in:where子句?

时间:2014-05-23 07:01:22

标签: clojure

我正试图解决类似于Einstein's riddle的谜语。要解决此问题,我使用的是library for making permutations

首先,我定义了主题的所有排列

(def auta (permutations [:Opel :Jeep :Renault :Octavia :Peaguot]))
(def skym (permutations [:pes :rodina :kamaradka :pratele :sam]))
(def mena (permutations [:Honza :Viktor :Marek :Ota :pavel]))
(def prace (permutations [:Student :Malir :Technik :Prog :nic]))
(def typ  (permutations [:Wherti :Myst :Multi :trad :earth]))

接下来,我列出解决方案矩阵

(def all (for 
[a (doall auta) s (doall skym) m (doall mena) p (doall prace) t(doall typ)]
[a s m p t]))

这是我想要的,我可以打印第一项

(print (take 1 all))

This will show me:

([(:Opel :Jeep :Renault :Octavia :Peaguot) (:pes :rodina :kamaradka :pratele :sa
m) (:Honza :Viktor :Marek :Ota :pavel) (:Student :Malir :Technik :Prog :nic) (:W
herti :Myst :Multi :trad :earth)])nil

现在我想在for中添加一个条件(起初我想添加条件:pavel是排列的第一个名字。

(def all (for 
[a (doall auta) s (doall skym) m (doall mena) p (doall prace) t(doall typ)
:when (= (m 1) :pavel) ]
[a s m p t]))

我以

结尾
CompilerException java.lang.ClassCastException: clojure.lang.LazySeq cannot be c
ast to clojure.lang.IFn, compiling:(C:\Users...

我需要改变条件才能让它运行?

P.S。:我尝试做(doall m)之类的事情,但它没有帮助。

1 个答案:

答案 0 :(得分:2)

问题是permutations返回一个seq并且您尝试使用(m 1)访问该seq的第一个元素(因为索引从0开始,因此也是错误的) 。但是,这仅适用于矢量:

(def sq (range 1 5))
(def v  (vec sq))

(sq 1) ; => ClassCastException clojure.lang.LazySeq cannot ...
(v 1)  ; => 2
(v 0)  ; => 1 (this is the actual first element)

解决方案:使用nth

(nth sq 0) ; => 1
(nth v 0)  ; => 1