[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
srfi-42
- 先行評価的内包表記 このモジュールはジェネリックな内包表記(comprehension)機構を提供します。 この機構は他の言語(Haskell、Pythonなど)では組み込みの機構になっていま す。この機構は豊富な操作手続を提供しているので、リストジェネレータとい うだけではなく、ジェネリックなループ構文(Common Lisp の loop マ クロ並みに強力/邪悪だという人もいます)を提供しています。
この機構は先行評価的に走ります。すなわち、リストを生成する場合、評価時 にすべてのリストを生成します。要素を要求駆動的に生成するわけで はありません。それゆえ、無限列を表現することはできません。それが自然に できる Haskell とは違います。Schemeにおいては無限列を扱うのなら遅延評 価をするように構築されたストリームが使えます。
いくつかの例からはじめましょう。
5番目までの整数の自乗のリストを生成しましょう。
(list-ec (: i 5) (* i i)) ⇒ (0 1 4 9 16) |
数の対(x y)
の集合を生成します。ここでx
は
2以上 5未満、y
は1以上 x 未満です。
(list-ec (: x 2 5) (: y 1 x) (list x y)) ⇒ ((2 1) (3 1) (3 2) (4 1) (4 2) (4 3)) |
上の2つの例はHaskellで書くと以下のようになります。
[ i*i | i <- [0..4] ] [ (x,y) | x <- [2..4], y <- [1..x-1] ] |
違いに注意:(1) Haskellでは要素になる本体部が先にきて、そのあとに修飾 部(セレクタ)がきます。SRFI-42では本体部は最後になります。(2) SRFI-42で は範囲指定の下限はそれを含み、上限はそれを含みません。
a^3+b^3 = c^3+d^3
を満すような数字の集合(a b c d)
を列挙し
ましょう。
(define (taxi-number n) (list-ec (: a 1 n) (: b (+ a 1) n) (: c (+ a 1) b) (: d (+ c 1) b) (if (= (+ (expt a 3) (expt b 3)) (+ (expt c 3) (expt d 3)))) (list a b c d))) |
リストだけではなく、他のシーケンスも生成できます。
(vector-ec (: i 5) i) ⇒ #(0 1 2 3 4) (string-ec (: i 5) (integer->char (+ i 65))) ⇒ "ABCDE" |
畳み込み演算も適用できます。
(sum-ec (: i 1 100) i) ⇒ 4950 ;; 1以上100未満の整数の和 (product-ec (: i 1 10) i) ⇒ 362880 ;; 1以上10未満の整数の積 |
それぞれの内包表記は以下のような形式になります。
(comprehension-macro qualifier … body) |
qualifierごとにbodyをくりかえし評価します。内包表記の種類 によって、bodyの結果は(リスト、ベクタ、文字列などに)集約されるか、 (sum、product、min、maxなどによって)畳み込まれるか、あるいは、単に捨て られます。
いくつかの内包表記では、追加の値がqualifiersの前か、bodies の後に置かれます。
[SRFI-42]
[SRFI-42]
[SRFI-42]
[SRFI-42]
[SRFI-42]
[SRFI-42]
[SRFI-42]
[SRFI-42]
[SRFI-42]
[SRFI-42]
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated by Shiro Kawai on October, 7 2008 using texi2html 1.78.