甲府方重信Blog

...Shigenobu Koufugatas Blog

  • Increase font size
  • Default font size
  • Decrease font size
Error
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
Home 業務日誌 Adaプログラミング Adaチュートリアル セクション11.4 GADTs対GADOs

Adaチュートリアル セクション11.4 GADTs対GADOs

E-mail Print PDF

セクション 11.4 - GADTs 対 GADOs

前のセクションで作成したスタックパッケージは、ジェネリックではないバージョンに比べて、かなりの柔軟性を持っています。私たちは異なった型を取り扱うために、異なったジェネリックスを実体化することができます。私たちは、いくつかのスタックを得るために同じ型に対して、複数回の実体化を行なうことさえ可能です。

しかしながら、このパッケージは可能な限り柔軟というわけではありません。私たちは引数としてスタックに渡すことができませんし、これらの配列を作成することもできません。(おそらく、私たちはスタックの配列を作りたいと思うことでしょう)

もし、ジェネリック・パッケージの内部において、私たちが新しい型(たとえば、「Stack」)を定義しており、この新しい型を使用するようにすべての操作を変更していれば、私たちはさらに柔軟性を与えることが可能となったでしょう。その場合、この新しい型を使用して、私たちは複数のスタックを渡すことが可能になり、配列にスタックを使うようなことも可能となります。ここではそのようなGeneric_Stackパッケージのスペックを掲載します。

  generic
    Size : Positive;
    type Item is private;
  package Generic_Stack is
    type Stack is limited private;
    procedure Push(S : in out Stack; E : in  Item);
    procedure Pop (S : in out Stack; E : out Item);
    Overflow, Underflow : exception;
  private 
    type Stack is array(1 .. Size) of Item; 
  end Generic_Stack;

Generic_Stackパッケージのこのバージョンと、前のバージョンを比較してみましょう。

  generic
    Size : Positive;
    type Item is private;
  package Generic_Stack is
    procedure Push(E : in  Item);
    procedure Pop (E : out Item);
    Overflow, Underflow : exception;
  end Generic_Stack;

Generic_Stackの新しいバージョンは、ジェネリック抽象データタイプ(GADT)と呼ばれているものの例です。ジェネリック抽象データタイプは、他の操作に対して中心となるデータ型を定義したジェネリックのことです。そうすると、パッケージの利用者は、レコードや配列にこれらの値を利用するようなことが可能となります。前のセクションで私たちが見てきたバージョンは、ジェネリック抽象データオブジェクト(GADO)と呼ばれています。プログラマーは、操作が固定された集合(プッシュとポップのような)を持つ「機械」としてGADOのそれぞれの実体を考えることが出来ます。GADTsは、プログラマーがジェネリックを実体化させなければならないので、若干利用に負担が要求されます。そこでは、使用しようとしている(新しい型の)値を宣言します。プログラマーは、それぞれのオブジェクト(つまりスタックのような)GADTが使用するそれぞれのGADT操作について記述しなければなりません。この若干の追加作業のおかげで、GADTsはより多目的に利用できるのです。たとえば、もしプログラマーがGADTを用いてスタックの配列を作りたいと思っているなら、それは簡単です。それに比べて、GADOsの配列を作成するのは事実、実用的とはいえません。それゆえ、一般的にはプログラマーはGADTとしてジェネリック・パッケージを開発すべきで、GADOは薦められないのです。(AQ&Sは、特に第8章においてこの点を薦めています)

私たちの新しいGeneric_StackのGADTバージョンを使用するには、私たちはまず、それを実体化させなければなりません。ここではその例を掲載します(私たちはそれを同じ方法で実体化していることに注意してください)

  package Stack_Int is new Generic_Stack(Size => 200, Item => Integer);

しかしながら、ここで私たちは新しい型を持っています。私たちはこの型の変数を作成する必要があるのです。たとえば、

  with Stack_Int; use Stack_Int;
  ...
  My_Stack : Stack;  -- Stack_Int's Stack type.

様々な命令を実行するためんひ、私たちはここでスタックが使用するものを伝える必要があります。

  Push(My_Stack, 7);

もしプログラマーはこのコンポーネントの再利用性について非常に関心を抱いているなら、プログラマーは可能な限り柔軟にしておくようにすべきです。たとえば、プログラマーが他の再利用可能なコンポーネントから、複雑なデータ構造を作成するために再利用可能なコンポーネントを「構成」することが可能となります。この方法をテストするためのシンプルな方法は、再利用可能なコンポーネント自体を構成しようと試みることです。[Wheeler 1992]. 私たちがここまでで見てきたスタックパッケージは、多くの点で良い状態となっていますが、それはうまく構成されていません。私たちは複数のスタックのスタックを作成することができません。なぜでしょうか。私たちの新しいバージョンにおける「Stack」がたがlimited private型だからです。これは代入操作を提供していません。しかしながら、Item型はprivateです。私たちはItemにプッシュとポップを実装するために代入操作を必要としたからです。

この解決法は単純です。私たちは、スタック同士でも代入をサポートすればよいのです。一つの方法は、Stackをprivate型にすることで、Adaに標準の代入操作を許可することになります。よりよい解決法は、「Controlled」方を使うことで、これはレッスン7で議論しています。そうすれば、私たちはより代入操作を制御することが可能となり、私たちの代入文を実装するために使用することができます。私たちはこれについて、少し後で見ていくことにしましょう。

出典: http://www.adahome.com/Tutorials/Lovelace/s11sf.htm

Last Updated on Monday, 02 April 2012 11:50  

ニュース速報

さっきの件だが、資料の候補をあげて、増田さんに依頼メールを送った。

うまく、話がつながるとよいのだが。さて、どうなることやら。