eli*_*ocs 5 clojure variadic-functions
我正在学习Clojure解决4clojure上列出的问题.其中一个练习是max
使用变量参数创建自己的函数.
我正在尝试使用REPL解决这个简单的问题,我得到了这个解决方案:
(defn my-max
[first & more] (calc-max first more))
(defn calc-max
[m x]
(cond (empty? x) m
(> (first x) m) (calc-max (first x) (rest x))
:else calc-max m (rest x)))
Run Code Online (Sandbox Code Playgroud)
哪个工作正常,但练习不允许使用,def
因此我必须将两个功能合二为一.当我calc-max
用它的代码替换引用时,结果是:
(defn my-max
[first & more]
((fn calc-max
[m x]
(cond (empty? x) m
(> (first x) m) (calc-max (first x) (rest x))
:else calc-max m (rest x)))
first more))
Run Code Online (Sandbox Code Playgroud)
但是这段代码不起作用并返回下一个错误:
user=> (my-max 12 3 4 5 612 3)
java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud)
我想这个错误来自于试图评估calc-max
函数的结果,我想这是我的语法错误,但我无法弄清楚如何解决它.
Jus*_*mas 14
这是我用来解决它的功能.关键是不要使用max.
(fn [& args] (reduce (fn [x y] (if (> x y) x y) ) args ) )
Run Code Online (Sandbox Code Playgroud)
真正的错误是你调用参数first
- 它将实际first
函数重新绑定到数字!只需将名称更改为其他名称,您的变体即可.虽然它可能更好地明确命名函数,而不是调用匿名函数,例如,您可以calc-max
使用letfn
例如声明为本地函数.所以你的my-max
看起来像:
(defn my-max [ff & more]
(letfn [(calc-max [m x]
(cond (empty? x) m
(> (first x) m) (calc-max (first x)
(rest x))
:else (calc-max m (rest x))))]
(calc-max ff more)))
Run Code Online (Sandbox Code Playgroud)
虽然,我认为,您可以编写更简单的代码:
(defn my-max [& more] (reduce max more))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5193 次 |
最近记录: |