2011-11-15 71 views
0

我有一些Clojure代码看起来非常简单,但却抛出了IllegalArgumentException。作为参考,以下代码显示了我编码的4个函数。我的错误在于第四。非法参数异常 - Clojure

"Determine candy amount for first parameter. Returns even integers only (odd #'s rounded up)." 
(defn fun1 [x y] (if (= (rem (+ (quot x 2) (quot y 2)) 2) 1) (+ (+ (quot x 2) (quot y 2)) 1) (+ (quot x 2) (quot y 2)))) 

"Play one round. Returns vector with new values." 
(defn fun2 [[x y z t]] (vector (fun1 x z) (fun1 y x) (fun1 z y) (+ t 1))) 

"Yield infinite sequence of turns." 
(defn fun3 [[x y z t]] (if (= x y z) (vector x y z t) (iterate fun2 [x y z t]))) 

(defn fun4 [[x y z t]] (take-while #(not= %1 %2 %3) (fun3 [x y z t]))) 

第四个函数调用第三个函数,直到值x y和z不相等。该代码正确编译但我得到以下序列中的REPL:

Clojure 1.1.0 
user=> (load-file "ass8.clj") 
#'user/fun4 
user=> (fun4 [10 10 10 1]) 
java.lang.IllegalArgumentException: Wrong number of args passed to: user$fun4--21$fn 
(user=> (fun4 [[10 10 10 1]]) 
java.lang.IllegalArgumentException: Wrong number of args passed to: user$fun4--21$fn 
(user=> (fun4 10 10 10 1) 
java.lang.IllegalArgumentException: Wrong number of args passed to: user$fun4 (NO_SOURCE_FILE:0) 

只有第一个表达式是真的正确的,但我在做,我已经尝试了所有可能的组合点。任何人都可以揭示这个神秘错误吗?可能在您自己的Clojure环境中测试它..?

作为一个附注,当x = y = z时不应该fun3停止。它现在似乎给了无限的序列,所以如果看起来是多余的。

回答

1

与参数您的评论上面,你可以使用下面代码(FUN1使用现有的代码)

(defn fun2 [v] 
     (loop [[a b c d] v] 
       (if (= a b c) 
        [a b c d] 
       (recur [(fun1 a c) (fun1 b a) (fun1 c b) (+ d 1)])))) 

你并不真的需要FUN3和FUN4

0

我不知道你想做什么,但对我(fun3 [10 10 10 1])评估为[10 10 10 1]

由于这只是一个普通的老向量的第一件事情,你的匿名函数被调用,只是数量10当它期待3个参数。

+0

在写我的回复时,我意识到了什么是根本问题。基本上,当三个值(例如10 10 10)相等时,“游戏”应该停止。要做到这一点,我想fun4是一个执行,直到x y和z(来自fun3的返回值)相等。我想让函数3自己做,但我不知道如何使用解构向量返回值进行条件检查。 –

1

取而就像地图,它需要来自集合的值,并检查谓词(即谓词将获得一个参数)。