再帰データ型のソースを表示
←
再帰データ型
ナビゲーションに移動
検索に移動
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループに属する利用者のみが実行できます:
登録利用者
。
このページのソースの閲覧やコピーができます。
{{型システム}} '''再帰型'''({{lang-en-short|recursive type}})とは、型の定義中にそれ自身の型が出現するような[[再帰]]する型のこと。[[相互再帰]]により直接は現れないものもある。'''再帰データ型'''({{lang-en-short|recursive data type}})とは、[[データ型]]における再帰型のこと。 == 例 == === 再帰データ型 === 多くのプログラミング言語では名前付きクラスで再帰型を扱うことが出来る。下記は [[Java]] での例。Tree のクラス定義の中で Tree を使用している。 <syntaxhighlight lang="Java"> class Tree { Tree[] children; } </syntaxhighlight> また、[[Haskell]]での[[リスト (抽象データ型)|リスト]]型を示す。これは、リスト a は空のリストの場合と 'a' を先頭に持つリストの場合があることを示している。 <syntaxhighlight lang="haskell"> data List a = Nil | Cons a (List a) </syntaxhighlight> === 再帰型エイリアス === 型エイリアスや型シノニムで再帰が使えるかどうかはプログラミング言語次第である。 [[TypeScript]]<ref>[https://devblogs.microsoft.com/typescript/announcing-typescript-3-7/#more-recursive-type-aliases (More) Recursive Type Aliases - Announcing TypeScript 3.7 - TypeScript]</ref> などでは型エイリアスの中でも再帰が利用可能である。下記は TypeScript の例だが、型エイリアスだけで木構造の型を表現できる。 <syntaxhighlight lang="TypeScript"> type Tree = number | Tree[]; let tree: Tree = [1, [2, 3]]; </syntaxhighlight> しかしながら、Haskellや[[OCaml]]や[[Miranda]]の型シノニム宣言では再帰は許されていないので、以下のような Haskell での型定義は不正である。 <syntaxhighlight lang="haskell"> type Bad = (Int, Bad) type Evil = Bool -> Evil </syntaxhighlight> それに対し、見た目は等価に思える[[代数的データ型]]は正当であり利用可能である。 <syntaxhighlight lang="haskell"> data Good = Pair Int Good data Fine = Fun (Bool->Fine) </syntaxhighlight> ==理論== 型システムは名前的型システムと構造的型システムに分かれる<ref>{{Cite book|和書|author=Benjamin C. Pierce |title=型システム入門 −プログラミング言語と型の理論− |publisher=オーム社 |date=2013-03-26 |isbn=978-4274069116 |chapter=19.3 名前的型システムと構造的型システム}}</ref>。名前的型システムは Java を始め、多くのプログラミング言語で採用されていて、型に名前を付け、Java なら extends で何を継承しているか型の名前を使って記載する方法で、それを見れば再帰型であっても部分型関係(継承しているかどうか)は簡単に分かる。構造的型システムは、型の名前で判定するのではなく、型の構造で部分型関係にあるかどうか(関数の引数に渡せるかどうかなど)を判定する。以下、ここで述べるのは、構造的型システムでの再帰型の理論である。 [[型理論]]では、再帰型の一般形はμ型構築子を用いて μα.T で表される。ここで型変数 α は型そのものであると共に、型 T の中にも現われる可能性がある。[[部分型]]関係かどうかは S <: T と記載する。名前的型システムの Java ならば S extends T または S implements T (ただし親クラスを Object までたどる)であることを意味する。 例えば、自然数を Haskell のデータ型として表すと次のようになる([[ペアノの公理]]参照): <syntaxhighlight lang="haskell"> data Nat = Zero | Succ Nat </syntaxhighlight> また、型理論では <math>nat = \mu \alpha. 1 + \alpha</math> となる。ここでは、Zero と Succ コンストラクタで表現されており、Zero は引数をとらず(型理論の定義の <math>\alpha</math>に相当)、Succ は別の Nat を引数としている(型理論での定義の<math>1 + \alpha</math>に相当)。 構造的型システムでの再帰型には、同型再帰型(iso-recursive type)と同値再帰型(equi-recursive type)の2つの形式がある。同型再帰型の実装は簡単であるが、同値再帰型は議論と証明が複雑で、ほとんどのプログラミング言語は名前的型システムか構造的型システムの同型再帰型を使用している。 ===同型再帰型=== 同型再帰型では、再帰型 <math>\mu \alpha . T</math> とその展開結果である <math>T[\mu \alpha.T / \alpha]</math> は別の型であり、特殊な項構成 ''fold'' と ''unfold'' で識別され、これらの間で[[同型写像]]を構成する。正確に記せば、<math>\mbox{fold} : T[\mu\alpha.T/\alpha] \to \mu\alpha.T</math> と <math>\mbox{unfold} : \mu\alpha.T \to T[\mu\alpha.T/\alpha]</math> であり、これらは互いに[[写像#逆写像|逆関数]]である。 部分型付けにおいてよく使われる方法として Amber 規則があり、μX.S <: μY.T かどうかを判定するにあたり、X <: Y という仮定を置いた上で、S <: T であれば、μX.S <: μY.T とする、という判定方法である。Java は構造的型システムではないが、分かりやすくするために Java の表記方法を使うと、 <syntaxhighlight lang="Java"> class ListA { Integer value; ListA next; } class ListB { Object value; ListB next; } </syntaxhighlight> で、ListA <: ListB であるかの判定をするにあたり、X は ListA の内側で再帰的に使っている ListA を指し、Y は ListB の内側で再帰的に使っている ListB を指すので、X <: Y であるという仮定を置いて、残りの value の部分が Integer <: Object なので、ListA <: ListB であると判定する方法である。再帰型同士しか比較しなく、再帰型を内部で利用している場合はそれを展開したりしないので、部分型付けの判定が有限時間で終わることが分かる。Amber 規則で出来ることは、概ね名前的型システムに近い。書籍『型システム入門』<ref name="TAPL">{{Cite book|和書|author=Benjamin C. Pierce |title=型システム入門 −プログラミング言語と型の理論− |publisher=オーム社 |date=2013-03-26 |isbn=978-4274069116 }}</ref>の「21.11 同型再帰型の部分型付け」で解説されている。 ===同値再帰型=== 同値再帰規則では、再帰型 <math>\mu \alpha . T</math> とその展開結果の <math>T[\mu\alpha.T/\alpha]</math> は「等価」である。ここで等価とは、この2つの型表現が同じ型を表していると理解されることを示す。実際、同値再帰型の理論ではさらに、無限に展開したときに等価となる2つの型表現は等価であるとするのが一般的である。型を木構造で表現したときに、当然であるが、無限の大きさの木構造同士が部分型関係にあるかどうかを有限時間で判定することは不可能である。しかしながら、再帰型の表現方法を正則型に制限すると、部分型関係にあるかどうかを、有限時間で判定出来るアルゴリズムが存在する。そして、そのアルゴリズムの正しさの証明は、無限を厳密に扱うために、余帰納法を使用する。正則型がなんであるかや、判定アルゴリズムとその証明は、書籍『型システム入門』<ref name="TAPL"/>の「第21章 再帰型のメタ理論」で解説されている。 このような規則の結果として、同値再帰型は同型再帰型よりも遥かに複雑な[[型システム]]を提供する。型検査のようなアルゴリズム上の問題や[[型推論]]も同値再帰型の方が難しい。 == 関連項目 == * [[再帰]] == 参照 == {{reflist}} {{FOLDOC}} {{データ型}} {{DEFAULTSORT:さいきてたかた}} [[Category:データ型]] [[Category:データ構造]]
このページで使用されているテンプレート:
テンプレート:Cite book
(
ソースを閲覧
)
テンプレート:FOLDOC
(
ソースを閲覧
)
テンプレート:Lang-en-short
(
ソースを閲覧
)
テンプレート:Reflist
(
ソースを閲覧
)
テンプレート:データ型
(
ソースを閲覧
)
テンプレート:型システム
(
ソースを閲覧
)
再帰データ型
に戻る。
ナビゲーション メニュー
個人用ツール
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
ソースを閲覧
履歴表示
その他
検索
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
特別ページ
ツール
リンク元
関連ページの更新状況
ページ情報