保型汎用的なη-拡大
-
26-09-2019 - |
質問
うになっている: 書い小さな通訳できるシステムの構文ファイルでのシーケンス業務として数千人のデータセットへのシーケンススペースを最終値らかにすることである。編集通訳者の一覧の純粋な機能という二つの引数:データセットの実行コンテキスト各機能を返します変更の実行コンテキスト:
type ('data, 'context) interpreter = ('data -> 'context -> 'context) list
のコンパイラは基本的にはトークナイザに最後のトークンを指示マッピングステップを使用した地図の説明以下のように定義して計算します:
type ('data, 'context) map = (string * ('data -> 'context -> 'context)) list
典型的な通訳の利用は以下のようなものです:
let pocket_calc =
let map = [ "add", (fun d c -> c # add d) ;
"sub", (fun d c -> c # sub d) ;
"mul", (fun d c -> c # mul d) ]
in
Interpreter.parse map "path/to/file.txt"
let new_context = Interpreter.run pocket_calc data old_context
の問題: 思っ pocket_calc
通訳の仕事を任意のクラスを支援する add
, sub
や mul
方法、および対応する data
typeることができますの整数で一つのコンテキストクラスおよび浮動小数点数た。
しかし、 pocket_calc
定義としての価値ではない機能で、タイプシステムは、汎用タイプ:初めてで使用すると、 'data
や 'context
種類は、種類のあらゆるデータおよび文脈の最初の提供、通訳者が永遠に対応していないその他のデータや文脈です。
実行可能な解決策であeta-拡張の定義に通訳をその型パラメータを汎用:
let pocket_calc data context =
let map = [ "add", (fun d c -> c # add d) ;
"sub", (fun d c -> c # sub d) ;
"mul", (fun d c -> c # mul d) ]
in
let interpreter = Interpreter.parse map "path/to/file.txt" in
Interpreter.run interpreter data context
しかし、このソリューションは、容認できない理由による
とは明らかな関連は見られなかっ統の通訳ないのと、大幅に劣化します。でも、マッピングステップ(回転、トークンリストへの通訳をマップリスト)の要因が顕著に減速した。
私のデザインに依存してすべての通訳装で初期化をしましたが、コンパイラの問題の警告でもトークンにロードされたファイルには合わないラインのmapリスト、見ておきたいすべての警告時のソフトウェアを開始(個人通訳がある。
私た再利用した地図リストに複数の通訳者から独自にまたはprepending追加の説明(例えば、
"div"
).
の質問: 方法はありますの型パラメトリック以外のeta-拡大?もしかした巧妙なトリックを伴うモジュールの署名または相続?さき、本当にありがとうを軽減するためには三つの課題にしていま述するためにeta-拡大、受け入れ可能な解決策?感謝です。
解決
実行可能な値段が高くなりますが、etaの拡大- 定義の通訳する 型パラメータで汎用:
let pocket_calc data context =
let map = [ "add", (fun d c -> c # add d) ;
"sub", (fun d c -> c # sub d) ;
"mul", (fun d c -> c # mul d) ]
in
let interpreter = Interpreter.parse map "path/to/file.txt" in
Interpreter.run interpreter data context
しかし、このソリューションは、容認できない の理由による
- とは明らかな関連は見られなかっ統の通訳ないという、 大幅に劣化します。でも、マッピングステップ(回転トークン リストへの通訳者用の地図 リスト)の要因が顕著に減速した。
でrecompilesの通訳時にでることができます。の適切な形でもこのような(および技術的には、場合には一部の解釈 Interpreter.run
へ interpreter
できるいくつかの計算は、その fun
があります。
let pocket_calc =
let map = [ "add", (fun d c -> c # add d) ;
"sub", (fun d c -> c # sub d) ;
"mul", (fun d c -> c # mul d) ]
in
let interpreter = Interpreter.parse map "path/to/file.txt" in
fun data context -> Interpreter.run interpreter data context
他のヒント
行きたいという問題が多型お業務におい閉じたパラメトリックタイプ(工のためのすべてのデータは、以下の演算プリミティブ)の代わりを持つ型を示すパラメータを固定データ型になります。しかし、奥高尾にひっそりと建つ料亭。は取りにくいということで、コードは自くとしていたことが分かりました。
仮に指定されたタイプのためのプリミティブ:
type 'a primitives = <
add : 'a -> 'a;
mul : 'a -> 'a;
sub : 'a -> 'a;
>
使用するうえで重要な場所にあたり、多型による構造物やオブジェクト
type op = { op : 'a . 'a -> 'a primitives -> 'a }
let map = [ "add", { op = fun d c -> c # add d } ;
"sub", { op = fun d c -> c # sub d } ;
"mul", { op = fun d c -> c # mul d } ];;
返されますが、以下のデータagnosticタイプ:
val map : (string * op) list
編集: についての解説の異なる操作の種類、なんなのかのレベルでの柔軟性です。ないと思いますがミックス事業別のプリミティブのリストで、だから利益を得らspecifities各:ですのみを変換"の動作を追加/sub/ul""行動作を追加/sub/ul/div"としていまcontravariantのプリミティブ型が確実になっている。
より実践的なレベルですが、そのデザインが必要となり異なる"動作"タイプ毎にプリミティブタイプです。でき、しかし、元parametrizedのプリミティブ型の返却の動作タイプです。
わからないのかどうなの直subtyping関係の異なるプリミティブです。問題はこれが必要なsubtyping関係の元、と思いまして、Caml.きし、簡単な形で明示的にsubtypingのではなく鋳造 a :> b
, を使用し機能 a -> b
)を構築し、二次元,contravariant、それを地図からプリミティブ型の他に、築地図からジェスチャ操作カスタマイズができる。
でできること、異なる巧妙な表現に進化し、より簡単な解決が可能です。最初のクラスのモジュールの3.12がっていく傾向を強めても第一級の存在種類はこちらまrhater利用ユニバーサルタイプ。
解釈の頭の動作reifications
他地域のタイピングの問題なんなのかまだ見出しました。を行う排除の解釈によるオーバーヘッドビルディング"の時間"(使用前の業務、閉鎖に対応するa-言語表現の自動作します。
私の経験上、このというアプローチは一般的になく解釈のオーバーヘッドまで移動しまう。作成した場合は、お休naïvelyての構文解析の流れの制御を再現閉鎖層:閉鎖を通その他の閉鎖等 として構文解析コード"の解釈"の入力を作成する。取り付けが確実に行われ、コストの構文解析が可能入の流れの制御が重ねの上に成り立っています。Additionnaly、閉鎖が痛みを直接操作する:いうよう十分注意してください約比較事業例えば、直列化など。
と思いま、長期的に中間"reified"言語を表す操作:単純代数のデータタイプのための算術演算を実行するよう構築からテキスト表現。ことができようとしてい止め"の時間"からなくなったの演奏よりもはるかに直訳する場合、メモリー中の表現です。また、やプラグインの仲介分析装置/トランス業務を最適化し、例えば今から"連想のバイナリ操作"モデル"n-ary事業"のモデルがより効率的に評価されます。