4

mapは関数とリストを取り、その関数をリストのすべての要素に適用します。例えば、

(map f [x1 x2 x3])
;= [(f x1) (f x2) (f x3)]

数学的には、リストは自然数 ℕ の部分関数です。x : ℕ → Xが何らかのリストであり、f : XYが何らかの関数である場合、 map は ( f , x ) のペアをリスト f○x : ℕ → Yに取ります。したがって、少なくとも単純なケースでは、map と comp は同じ値を返します。

ただし、複数の引数を指定して map を適用すると、さらに複雑な処理が行われます。例を考えてみましょう:

(map f [x1 x2 x3] [y1 y2 y3])
;= [(f x1 y1) (f x2 y2) (f x3 y3)]

ここでは、同じ定義域を持つ 2 つのリストx : ℕ → Xy : ℕ → Yと、型f : X → ( YZ ) の関数があります。タプル ( fxy ) を評価するために、マップは舞台裏でさらに作業を行う必要があります。

最初に、 mapは diag( x , y )(n) = ( x (n), y (n))によって定義される対角積リスト diag( x , y ) : ℕ → X × Yを作成します。

次に、関数をカリー-1 ( f ) : X × YZにアンカリー化します。最後に、map はこれらの操作を組み合わせて、curry -1 (f) ○ diag( x , y ) : ℕ → Zを取得します。

私の質問は次のとおりです。このパターンは一般化されていますか? すなわち、3 つのリストx : ℕ → Xy : ℕ → Yおよびz : ℕ → Zと、関数f : X → ( Y → ( ZW ))) があるとします。map はタプル ( f , x , y , z ) をリスト Curry -2 (f) ○ diag( x , y , z ) : ℕ → Wに送りますか?

4

3 に答える 3

3

役立つかどうかはわかりませんが、次のとおりです。

  • Clojure には、Haskell のようなカリー化はありません。部分的な関数適用はありますが、カリー化とは異なります。
  • Clojure のマップは、Haskell の zipWith、zipWith3 などに似ています
于 2013-09-17T18:11:56.067 に答える
1

技術的には、map はこのような合成関数と見なすことができますが、実際には、comp にはないオーバーヘッドが発生します。

map結果が最終的に読み取られたときにシーケンスを計算する遅延シーケンスを生成します。したがって、型式が意味する結果とは厳密には異なるシーケンスを返します。また、レイジーでチャンク化されているため、シーケンスのオーバーヘッドが追加され、評価順序が変更されます。

于 2013-09-17T18:14:28.987 に答える