2012-05-15 175 views
3

我正在研究clojure koans,并且函数中的其中一个问题需要进一步的解释让我“得到它”并拥有一段时间。我能写出满足问题的函数。但我不完全明白为什么所有的工作。匿名函数正在消耗另一个匿名函数 - clojure koan

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的值的诠释它代表做我得到一个错误?

Quentions 3.

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

为什么这不会引发错误(B A)B在这种情况下是5,它是一个符号。 括号中的第一项预计是函数还是特殊形式,除非它是一个列表?

+0

[Koans在github上(https://github.com/functional-koans/clojure-koans/blob/master/src/koans/functions.clj )。 –

回答

6
  1. 看你的表情在第一功能:

    (b a) 
    

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

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

    记住的Lisp评价规则:给予该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)))