データ型の強制
Mapleでは、プロシージャはパラメータのタイプを強制して宣言することができます。プロシージャが任意のタイプをどれも扱うことが可能な程度に同等の複数のデータタイプがある場合があります。しかし、異なるデータタイプのそれぞれを扱うプロシージャのコーディングは複雑な場合があります。そのようなプロシージャの作成のため、Maple はデータタイプの強制を用意しています。これは、さまざまなデータタイプを 1 つの希望するタイプに変換する機能です。
パラメータ強制を宣言する最も一般的な方法は、mMatrix に対する m~Matrix のように標準のMaple タイプの前にチルダ (~) を付けることです。コマンド ~Matrix がカレントモジュールのエクスポート、または最上位のコマンドとして存在する場合は、そのコマンドは入力がタイプ Matrix と一致しないときに実行されます。
>
|
p := proc( m::~Matrix )
whattype( m );
end;
|
| (1) |
上記のプロシージャは多くのデータタイプについて機能し、関数内では希望するタイプのみが表示されます。
>
|
p( Array( [ [ 1, 2 ], [ 3, 4 ] ] ) );
|
| (2) |
>
|
p( Vector[row]( [ 5,6,7 ] ) );
|
| (3) |
>
|
p( [ [ 1,2,3 ], [ 4,5,6 ], [7,8,9] ] );
|
| (4) |
与えられたタイプが希望のタイプに変換できない場合は、例外が発生します。
現在、Maple は ~Matrix、~Vector、および ~Array を実装しています。個々のヘルプページにはどのデータタイプがこれらの関数によって受け付けられるかが記述されています。 より上位の強制コマンドは将来の Maple のバージョンで実装される予定です。標準の Maple タイプについて、ユーザ独自の強制の定義には以下で記述する長い形式を使用するか、モジュールのエクスポートを使用することを推奨します。以下の例では、モジュール内でのプライベート強制ルーチンの宣言方法を説明します。"ModuleApply" を使用すると、モジュールはプロシージャと同様に動作しますが、モジュールの場合は他のメソッドとデータを関連付けることができます。
>
|
Frac := module()
local ModuleApply, ~rational;
~rational := proc( a::float ) convert(a,rational); end;
ModuleApply := proc( r::~rational ) frac(r); end;
end module;
|
| (5) |
| (6) |
| (7) |
強制は、コンテナのみを変更するのではなく、可能な場合は rtable のデータタイプを希望するデータタイプと一致するように調整します。
>
|
p_type := proc( m::~Matrix( datatype=float ) )
rtable_options(m,datatype);
end;
|
| (8) |
>
|
p_type( Matrix( [[1,2],[3,4]], datatype=integer ) );
|
| (9) |
>
|
p_type( Matrix( [[1/2,2/3],[3/4,4/5]], datatype=rational ) );
|
| (10) |
与えられた式が希望のタイプに変換できない場合は、例外が発生します。
>
|
p_type( Matrix( [[1*I,2*I],[3*I,4*I]], datatype=complex ) );
|
Error, invalid input: p_type expects its 1st argument, m, to be coercible to the type Matrix(datatype = float), but received Matrix(2, 2, [[I,2*I],[3*I,4*I]], datatype = complex)
| |
rtable の特定の形式から他のデータタイプへの強制の多くは、実際のデータのコピーの作成なしで行うことができます。Maple は希望するタイプに合わせて表示可能な、同じデータセットへのエイリアスを作成することができます。しかし、リストの rtable への変換や rtable タイプの変更では、データのコピーが必要なものがあります。コピーが作成されると、プロシージャ内で rtable を変更しても実際に渡される rtable には影響を与えません。そのため、インプレースで機能するプロシージャは自動強制ができません。
強制を行う ~ プロシージャから出力される値 NULL は、強制が失敗したことを示します。これは、外部プロシージャからの標準の invalid input エラーになります。
整数を入力として ~Array を直接呼び出すと、有効な強制ではないため NULL を出力します。同様に、第一パラメータを ~Array として宣言するプロシージャに 4 を渡すと、バックグラウンドで ~Array(4) を実行し、NULL を出力します。4 は強制されないためエラーが発生します。
>
|
proc( a::~Array ) a; end(4);
|
|
coerce() の長い形式
|
|
Maple では、強制の発生の度合いを明示的に指定できます。これは、coerce() パラメータ 修飾子を使用することにより行われます。coerce 修飾子は、タイプのシーケンスと強制プロシージャを指定します。強制プロシージャは単一タイプのパラメータを受け付け、そのパラメータを新規の式に変換するプロシージャです。メインプロシージャが呼び出されると、引数のタイプは強制プロシージャのパラメータタイプに対してチェックされます。パラメータタイプが引数のタイプと一致する最初の強制プロシージャが呼び出されます。これは、overloaded プロシージャの動作方法と同じです。強制プロシージャのマッチングのリターン値は、パラメータの値として使用されます。
>
|
p_string := proc( s::coerce( string, (s::name)->convert(s,string) ) )
s;
end;
|
| (11) |
渡されるパラメータが文字列タイプである場合は、強制ステートメントに記述されたタイプと一致するため、この文字列を未変更のまま渡します。
>
|
p_string( "a string" );
|
| (12) |
渡されるパラメータが名前タイプである場合は、2 番目の項目 (s::name)->convert(s,string) は名前を文字列に変換し、その文字列が p_string の引数として渡されます。
| (13) |
マッチする強制プロシージャがない場合は、エラーが発生します。
前の例ではプロシージャ宣言の arrow 形式を使用していますが、名前付きプロシージャも使用可能です。
>
|
p_proc := proc( A::coerce( Matrix, LinearAlgebra:-Simplify(a) ) )
A;
end proc:
|
>
|
p_proc( x + <1,2;3,4> );
|
| (14) |
LinearAlgebra:-Simplify は Matrix を出力しないことがあるため、p_proc は他のタイプを扱う必要があります。代わりに、リターン値タイプをチェックする別のプロシージャ内で実行し、希望するタイプでなかった場合は NULL を出力します。
>
|
LASimplify := proc(a)
local r := LinearAlgebra:-Simplify(a);
if r::Matrix then
return r;
else
return NULL;
end if;
end proc;
|
| (15) |
>
|
p_proc := proc( A::coerce( Matrix, LASimplify ) )
A;
end proc:
|
複数のタイプと強制ルーチンが指定できます。それらは順番に検証されます。
>
|
ModNearestP := proc( a::integer, p::coerce( prime, (a::posint)->nextprime(a), (a::negint)->`if`(type(-a,prime),-a,nextprime(-a)) ) )
a mod p;
end proc;
|
| (16) |
| (17) |
| (18) |
| (19) |
~Array 強制メソッドの強力な一面は、プロシージャの作者が 1 ベースおよび 0 ベースのどちらの配列も扱うことができることです。強制宣言 A~Array(0..) を使用すると、プロシージャはインデックス A[0] を最初の要素とする配列を常に得ることができます。この ~ ショートカットは、つぎのように長い形式で記述できます: Acoerce( {Array(0..)}, ~Array(0..) )ここで、渡される入力がタイプ {Array(0..)} と一致しない場合は、~Array(input,0..) は強制実行のために呼び出されます。この宣言には注意すべき特殊ケースが含まれます。Array(0..) は強制関数およびタイプとしてあいまいなため、これは A:coerce( Array(0..), ~Array(0..) として宣言できません。規則として、すべての関数形式は強制関数として扱われます。{Array(0..)} を中括弧で囲むと、タイプとして認識されます。
|
|
関連項目
|
|
Array, coerce, list , listlist, Matrix, Procedure Parameters, Procedures, rtable, Vector, ~Array, ~Matrix, ~Vector
|
|