使用可变参数定义我自己的 max 函数
我正在学习 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)))
效果很好,但练习不允许使用 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))
但是此代码不起作用并返回下一个错误:
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)
我猜这个错误来自于尝试评估 的结果>calc-max
函数,我猜这是我的语法错误,但我不知道如何解决它。
I'm learning Clojure solving the problems listed on 4clojure. One of the exercises is to create your own max
function with variable arguments.
I'm trying to solve this easy problem using the REPL and I got to this solution:
(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)))
Which works fine but the exercise doesn't allow the use of def
and therefore I must crunch both functions into one. When I replace the calc-max
reference with its code the result is:
(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))
But this code doesn't work and returns the next error:
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)
I guess this error comes from trying to evaluate the result of the calc-max
function and I guess it's a syntax error on my part, but I can't figure out how to resolve it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是我用来解决这个问题的函数。重点是根本不使用 max。
Here is the function I used to solve it. The point is not to use max at all.
真正的错误是您调用了参数
first
- 它将真正的first
函数重新绑定到数字!只需将名称更改为其他名称,您的变体就会起作用。虽然显式命名函数可能更好,但您可以使用letfn
将 calc-max 声明为本地函数,而不是调用匿名函数。所以你的my-max
看起来像:虽然,我认为,你可以编写更简单的代码:
Real error is that you called parameter
first
- it rebinds realfirst
function to number! Just change name to something other, and your variant will work. Although it maybe better explicitly name function, instead of calling anonymous function, for example, you can declarecalc-max
as local function usingletfn
, for example. So yourmy-max
will look like:Although, I think, that you can write simpler code:
您的函数不起作用,因为
fn
中的first
被视为函数而不是输入值。所以当你写它的时候,它不能将 12 转换为函数。简单地说,它可以重写为
或什至不重写为
fn
Your function doesn't work because
first
infn
treated as function and not as input value. So when you writeit's talling that can't cast 12 to function. Simply, it can be rewrited as
or even without
fn
详细说明一下您所看到的异常:每当 Clojure 向
您抛出类似的内容时,这意味着它试图调用一个函数,但它试图调用的不是一个函数,而是其他东西。当您有这样的代码时,通常会发生这种情况:
如果
smbl
引用一个函数,clojure 将使用参数 1 2 和 3 执行它。但是如果smbl
不引用函数函数,然后你会看到类似上面的错误。这是我查看代码时的指针,正如 4e6 指出的那样,(first x)
是这里的罪魁祸首,因为您将函数参数命名为first
。To elaborate a little more on the exception that you are seeing: whenever Clojure throws something like
at you it means that it tried to call a function but the thing it tried to call was not a function but something else. This usually occurs when you have code like this
If
smbl
refers to a function, clojure will execute it with parameters 1 2 and 3. But ifsmbl
doesn't refer to a function then you will see an error like the one above. This was my pointer in looking through your code and, as 4e6 pointed out,(first x)
is the culprit here because you named your function argumentfirst
.不如reduce那么好,但还可以吧:
(fn [& args]
(循环[l args, maxno (第一个参数)]
(如果(空?l)
最大号
(if (> maxno (第一个 l) )
(重复(剩余 l)maxno)
(recur (rest l) (first l))))))
我想可以使用 cond
Not as good as the reduce but ok ba:
(fn [& args]
(loop [l args, maxno (first args)]
(if (empty? l)
maxno
(if (> maxno (first l) )
(recur (rest l) maxno)
(recur (rest l) (first l))))))
Can use cond I suppose