Example10.5

10.5 For の一般化 (Generalizing For)

for 内包表記の翻訳が、メソッド map、flatMap、filter の存在だけに依存していることを見てきました。したがって、リスト以外のオブジェクトを生成するジェネレータについても、同じ記法を適用できます。それらのオブジェクトは3つのキーとなる関数 map、flatMap、filter だけをサポートすればよいのです。

標準 Scala ライブラリには、それら3つのメソッドと for 内包表記をサポートする抽象化が他にもいくつかあります。それらのいくつかは後の章で目にするでしょう。プログラマは自分が定義する型について for 内包表記を使えるようにするために、この原則を利用できます。そのような型は、単にメソッド map、flatMap、filter だけが必要なのです。

このことが役に立つ例はいくつもあります。たとえばデータベース・インタフェース、XML 木、オプション値などです。

一つ注意すべき点を。for 内包表記の翻訳結果に型整合性があることは、自動的には保証されません。これを保証するためには、map、flatMap、filter の型が、クラス List 中のそれらメソッドの型と本質的に似ていることが必要です。

より正確に言えば、for 内包表記を可能にしたい、パラメータ化されたクラス C[A] があるとしましょう。すると C は次のような型を持った map、flatMap、filter を定義しなくてはなりません。

def map[B](f: A => B): C[B] 
def flatMap[B](f: A => C[B]): C[B] 
def filter(p: A => Boolean): C[A] 

これらの型を Scala コンパイラの中で静的に強制することは、よい考えに思えます。たとえば for 内包表記をサポートするすべての型が、これらのメソッドを持つ標準トレイトを実装するよう要求するとかです(*1)。問題は、そのような標準的なトレイトはクラス C の同一性に対して抽象化、たとえば C を型パラメータとしてとるとか、をしなくてはならないことです。このパラメータは型コンストラクタであり、map や flatMap メソッドのシグネチャにおいて 複数の異なる 型に適用される、ということに注意すべきです。不運にも Scala の型システムはこのコンストラクトを表現するには弱過ぎます。なぜなら完全に適用される型である、型パラメータしか扱えないからです。

(*1) プログラミング言語 Haskell には同様のコンストラクトがあり、この抽象化は "monad with zero" と呼ばれています。


名前:
コメント:

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2011年02月24日 08:51
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。