これはMoritz Lenz氏のWebサイトPerlgeek.deで公開されているブログ記事"Perl 5 to 6" Lesson 21 - Subset Typesの日本語訳です。
原文はCreative Commons Attribution 3.0 Germanyに基づいて公開されています。
本エントリにはCreative Commons Attribution 3.0 Unportedを適用します。
Original text: Copyright© 2008-2010 Moritz Lenz
Japanese translation: Copyright© 2011 SATOH Koichi
NAME
"Perl 5 to 6" Lesson 21 - 派生型
SYNOPSIS
subset Squares of Int where { .sqrt.Int**2 == $_ };
multi sub square_root(Squares $x --> Int) {
return $x.sqrt.Int;
}
multi sub square_root(Num $x --> Num) {
return $x.sqrt;
}
DESCRIPTION
Javaプログラマは型のことをクラスかインタフェース(不具なクラスのようなもの)のように考えがちですが、その見方はPerl6においては狭すぎます。
型はもっと一般的に、コンテナが値に与えることができる制約です。「古典的な」制約はクラスX
あるいはそれを継承したクラスのインスタンスであることです。
Perl6にもX
クラスのインスタンスだとかY
ロールを実装しているとか、あるいはオブジェクトに対してこのコード片が真を返すといった制約があります。
最後に挙げたのが最も一般的なもので、これは派生型(Subset type)と呼ばれています:
subset Even of Int where { $_ % 2 == 0 }
# これで他の型名と同様にEvenが使えるようになった
my Even $x = 2;
my Even $y = 3; # 型不一致エラー
(試してみて下さい。Rakudoは派生型を既に実装していますが、派生型に基づいた多重ディスパッチはまだ実装されていません)(訳注: Rakudo* v2011.01で確認したところ、既に実装されているようです)
シグネチャで無名派生型を使うこともできます:
sub foo (Int where { ... } $x) { ... }
# あるいは変数を前に出して
sub foo ($x of Int where { ... } ) { ... }
MOTIVATION
コードの形で任意の型制約を許すことは究極の拡張性を与えてくれます: 現状の型システムが気に喰わなくとも、派生型による自分の型システムで包むことができます。
また、これはライブラリを容易に拡張可能にします: 扱えないデータに対して死ぬ代わりに、サブルーチンやメソッドは「悪い」データが単に多重ディスパッチャによって排除されると宣言できます。 もし排除されていたデータを誰かが扱いたくなったら、同名でそのデータを処理できる多重サブルーチンを簡単に追加できます。 この方法で例えば実数を扱う数学ライブラリを複素数を扱えるように拡張できます。
コメント
コメントを投稿