我正在研究clojure koans,函数中的一个问题需要进一步解释我"得到它"并且有一个aha时刻.我能够编写满足问题的函数.但我不完全理解为什么所有这些都有效.
Clojure> (= 25 ((fn [a b] (b a)) 5 (fn [n] (* n n))))
true
Run Code Online (Sandbox Code Playgroud)
问题1. 我不明白为什么会抛出错误:
Clojure> (= 25 ((fn [b a] (b a)) 5 (fn [n] (* n n))))
java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn
Run Code Online (Sandbox Code Playgroud)
因此,上述唯一的变化是切换b和a的顺序.在我的大脑中,我读到了"一个带有a和b"或"b和a"的函数,但它们如何被使用取决于随后的语句.为什么订单在这一点上很重要?
问题2.
Clojure> (= 25 ((fn [a] (5 a)) (fn [n] (* n n))))
java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn
Run Code Online (Sandbox Code Playgroud)
为什么当我将b的值替换为它所代表的int时,我会收到错误?
Qution 3.
((fn [a b] (b a)) 5 (fn [n] (* n n))))
Run Code Online (Sandbox Code Playgroud)
为什么这不会抛出错误(ba)b在这个例子中是5,这是一个符号.括号中的第一项预计是函数或特殊形式,除非它是一个列表?
在第一个函数中查看你的表达式:
(b a)
Run Code Online (Sandbox Code Playgroud)
既然b
是第一个,b
必须是一个功能.在你的第二个例子中,你试图传递5 b
,但是5不是函数.使用描述性名称,您可以看到您尝试使用5作为函数:
((fn [argument function] (argument function)) ;; problem!!
5
(fn [n] (* n n)))
Run Code Online (Sandbox Code Playgroud)
记住lisps的评估规则:给出这个s-expression:
(f x y z)
Run Code Online (Sandbox Code Playgroud)
计算f,x,y和z,并将f作为函数应用于x,y和z.
看到答案1 - '5'不是一个功能.使用描述性名称,并轻松发现问题:
((fn [function] (5 function)) ;; problem!!
(fn [n] (* n n)))
Run Code Online (Sandbox Code Playgroud)
改成:
((fn [a] (a 5)) ;; 'a' and '5' flipped
(fn [n] (* n n)))
Run Code Online (Sandbox Code Playgroud)
让它运行.
这不是问题: a
是5,b
是一个功能(b a)
.使用描述性名称更有意义:
((fn [argument function] (function argument))
5
(fn [n] (* n n)))
Run Code Online (Sandbox Code Playgroud)