3

私は clojure koans に取り組んでおり、関数の質問の 1 つは、「それを理解する」ためにさらに説明する必要があります。質問を満たす関数を書くことができます。しかし、すべてのビットが機能する理由が完全にはわかりません。

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 の値を b の値に置き換えると、エラーが発生するのはなぜですか?

質問 3。

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

これがエラー (ba) をスローしないのはなぜですか b この場合、シンボルである 5 です。括弧内の最初の項目は、リストでない限り、関数または特別な形式であると予想されますか?

4

1 に答える 1

6
  1. 最初の関数の式を見てください。

    (b a)
    

    bが最初なので、関数でなけれbばなりません。2 番目の例では、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)))
    
于 2012-05-15T16:51:38.513 に答える