Clojure - Currying 技术细节
Clojure - Currying technicalities
我知道 clojure 没有对 currying 的内置支持。但我想了解为什么这段代码失败的技术细节 -->
(defn area-of-triangle
"Takes the lengths a b and the angle c"
[a b c]
(Math/abs (* 0.5 a b (Math/sin c))))
(defn curry
[a]
(fn [b]
(fn [c] ((area-of-triangle a b c)))))
运行 repl 中的这个 -->
(def a (curry 3))
(def b (a 4))
(def c (b 54.7))
ClassCastException java.lang.Double cannot be cast to clojure.lang.IFn user$curry$fn__1737$fn__1738.invoke (:4)
有人可以解释一下这里发生了什么吗?为什么c不是三角形面积函数计算出来的值?
非常感谢,亚历克斯
因为这里调用了双函数:
((area-of-triangle a b c))
您正在将函数 area-of-triangle
的结果作为函数调用。
你有一组额外的括号:
(fn [c] ((area-of-triangle a b c)))
^
这是一个问题,因为 area-of-triangle
的计算结果是一个数字。假设它被评估为 10,那么你有:
(fn [c] (10))
这没有任何意义,因为 10 不可调用。
这里有两件事:
- 您在 (area-of-triangle a b c)
周围有额外的括号
- 柯里化可以使用partial函数
例如:
(defn area-of-triangle
"Takes the lengths a b and the angle c"
[a b c]
(Math/abs (* 0.5 a b (Math/sin c))))
(def a (partial area-of-triangle 3))
(def b (partial a 4))
(def c (b 54.7)) ;; 5.7698490053091875
我知道 clojure 没有对 currying 的内置支持。但我想了解为什么这段代码失败的技术细节 -->
(defn area-of-triangle
"Takes the lengths a b and the angle c"
[a b c]
(Math/abs (* 0.5 a b (Math/sin c))))
(defn curry
[a]
(fn [b]
(fn [c] ((area-of-triangle a b c)))))
运行 repl 中的这个 -->
(def a (curry 3))
(def b (a 4))
(def c (b 54.7))
ClassCastException java.lang.Double cannot be cast to clojure.lang.IFn user$curry$fn__1737$fn__1738.invoke (:4)
有人可以解释一下这里发生了什么吗?为什么c不是三角形面积函数计算出来的值?
非常感谢,亚历克斯
因为这里调用了双函数:
((area-of-triangle a b c))
您正在将函数 area-of-triangle
的结果作为函数调用。
你有一组额外的括号:
(fn [c] ((area-of-triangle a b c)))
^
这是一个问题,因为 area-of-triangle
的计算结果是一个数字。假设它被评估为 10,那么你有:
(fn [c] (10))
这没有任何意义,因为 10 不可调用。
这里有两件事:
- 您在 (area-of-triangle a b c) 周围有额外的括号
- 柯里化可以使用partial函数
例如:
(defn area-of-triangle
"Takes the lengths a b and the angle c"
[a b c]
(Math/abs (* 0.5 a b (Math/sin c))))
(def a (partial area-of-triangle 3))
(def b (partial a 4))
(def c (b 54.7)) ;; 5.7698490053091875