« リファクタリング | トップページ | 「Scheme の do」 その後 »

2009年2月22日 (日)

リスト内包表記

以前から、 Haskell の「リスト内包表記」に憧れていました。Scheme でもあんな風に書けたら……と思っていました。

それでググってみたら、 "SRFI-42" に "Eager Comprehensions" というのがありました。まさに「内包表記」です。 Gauche でも普通に使用できるようです。Haskell との違いは先行的評価であることと、表記する要素の順番。

先行的評価に関しては、自分が使用するときに気をつければいいのであまり気にならないのですが、表記の順序はちょっと気になります。

数学で集合を表現する場合、

A = {x | F(x)}

のように、まず集合の要素の代表を提示してから、要素の条件を示します。 Haskell はまさにその通りの順序なんですが、"SRFI-42" は条件を先に書かなければなりません。これが僕にはしっくりこないんですね。

それで他にもいろいろ探してみたら、なんと、自分の持っている「プログラミング言語 SCHEME」という本のサンプルを集めた章に「集合の構築」という名前で、リスト内包表記を実現する方法が載っていました。

その部分の説明を引用しておきます。

set-of 式は以下の形式となります。

(set-of value exp ...)

exp ... によって設定したバインドによって表現された集合の要素が value となります。それぞれの式 expt ... は以下のいずれかの形式になります。

  1. (x in s) 形式の式は x を集合 s の各要素にバインドします。このバインドは残りの式 exp ... および式 value から参照できます。
  2. (x is e) 形式の式は xe にバインドします。このバインドは残りの式 exp ... および式 value から参照できます。この形式は基本的に (x in (list e)) の省略形です。
  3. その他の形式の式は述語として扱われます。

例えば

(set-of x (x in '(a b c))) ; => (a b c) (set-of x (x in '(1 2 3 4 5)) (even? x)) ; => (2 4) (set-of (cons x y) (x in '(1 2 3)) (y is (* x x))) ; => ((1 . 1) (2 . 4) (3 . 9)) (set-of (cons x y) (x in '(1 2 3)) (y in '(a b))) ; => ((1 . a) (1 . b) (2 . a) (2 . b) (3 . a) (3 . b)) (set-of (list a b) (a in '(1 2 3 4 5)) (b in '(2 4 6 8)) (> (+ a b) 10)) ; => ((3 8) (4 8) (5 6) (5 8))

となります。

この本の著者は、私の使用している "Chez Scheme" の主要開発者ということもあり、今後はこちらを使っていこうと思っています。

「プログラミング言語 SCHEME」の英語版を "Chez Scheme" のホームページで読むことができますので、ソースコードが知りたい方はそちらをご覧ください ("The Scheme Programming Language" の "Section 9.3. A Set Constructor")。

« リファクタリング | トップページ | 「Scheme の do」 その後 »

Scheme」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/112020/44142559

この記事へのトラックバック一覧です: リスト内包表記:

« リファクタリング | トップページ | 「Scheme の do」 その後 »

2016年7月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
フォト

最近のトラックバック

無料ブログはココログ