3

我正在研究 clojure koans,函数中的一个问题需要进一步解释才能让我“明白”并有一个 aha 时刻。我能够编写满足问题的函数。但我不完全理解为什么所有的位都有效。

Clojure> (= 25 ((fn [a b] (b a)) 5 (fn [n] (* n n))))
true

问题 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

所以上面唯一的变化就是切换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

为什么当我用 b 的值代替它所代表的 int 时会出现错误?

问题 3。

((fn [a b] (b a)) 5 (fn [n] (* n n))))

为什么这不会引发错误 (ba) 在这种情况下 b 是 5,它是一个符号。除非是列表,否则括号中的第一项应该是函数或特殊形式?

4

1 回答 1

6
  1. 在第一个函数中查看您的表达式:

    (b a)
    

    因为b是第一个,b必须是一个函数。在第二个示例中,您尝试将 5 传递给b,但 5 不是函数。使用描述性名称,您可以看到您正在尝试使用 5 作为函数:

    ((fn [argument function] (argument function)) ;; problem!!
     5 
     (fn [n] (* n n)))
    

    记住 lisps 的求值规则:给定这个 s 表达式:

    (f x y z)
    

    计算 f、x、y 和 z,并将 f 作为函数应用于 x、y 和 z。

  2. 请参阅对 1 的回答——“5”不是函数。使用描述性名称,轻松发现问题:

    ((fn [function] (5 function)) ;; problem!!
     (fn [n] (* n n)))
    

    改成:

       ((fn [a] (a 5))  ;; 'a' and '5' flipped
        (fn [n] (* n n)))
    

    让它运行。

  3. 这不是问题: a是 5,b(b a). 使用描述性名称更有意义:

    ((fn [argument function] (function argument)) 
     5
     (fn [n] (* n n)))
    
于 2012-05-15T16:51:38.513 回答