通常、OCamlプログラムはオブジェクトの有無にかかわらず書くことができます。オブジェクトを使用することが最も有益なのはいつですか。また、オブジェクトを避ける必要があるのはいつですか。
1 に答える
一般的な経験則として、オブジェクトは使用しないでください。彼らがもたらす追加の複雑さは、それほど価値がないことがよくあります。それは他の言語にも当てはまるルールだと思いますが、それは別の話です。少なくともOCamlでは、客観的に(しゃれは意図されていません)、まれな場合を除いてオブジェクトを使用しないのが一般的な方法であると言うことができます。
オブジェクトは以下のバンドルを提供します:
- 関数のレコードを持ち運び、使用するための「標準」スタイル。多態的なタイプの可能性があります。
self
(実装継承)によるオープン再帰のための機能- 行多相(オープンオブジェクトタイプの場合)およびサブタイピング(クローズオブジェクトタイプの場合)を備えた構造的で拡張可能な製品タイプ
これらのいずれかを一緒に使用することも、別々に使用することもできます。
私の経験では、ポイント(1)だけでは、オブジェクトを使用する価値は特にありません。関数のレコードを使用するだけで、同じように明確になります。
オープン再帰/継承のユースケース
それどころか、ポイント(2)は、オブジェクト指向スタイルを使用するための正当な理由です。たとえば、Camlp4によってこのように使用されます。Camlp4は、何もせずにASTをフォールドするクラスを定義します。このトラバーサルオブジェクトを継承して、必要な構文構造にのみ必要な動作を実装できます(退屈なトラバーサル配管を延期します)。あなたの母クラス)。
たとえば、Camlp4Ast.mapオブジェクトを拡張して、OCaml抽象構文ツリーのCamlp4表現で単純なマップ関数を定義し、すべての構成をそれ自体に再帰的にマッピングすることができます。たとえば、すべての(fun x -> e1) e2
式をにマップするlet x = e2 in e1
場合は、このオブジェクトから継承し、メソッドをオーバーライドして、expr
必要な場合のみを処理し(左側は関数です)、もう一方を継承された動作に委任します。これにより、ボイラープレートコードを記述しなくても、この変換を完全なプログラムに再帰的に適用する方法を知っているオブジェクトが得られます。必要に応じて、この変換を追加の動作でさらに拡張できます。
オブジェクトタイプを楽しむ
ポイント(3)は、オブジェクトを「拡張可能なレコード」または「タイプレベルの配列」として使用する理由でもあります。一部のライブラリはオブジェクトタイプを使用しますが、実行時にはオブジェクトを使用しません。オブジェクトタイプをファントムタイプとして使用して情報を持ち運び、オブジェクトに対して実行できるより豊富なタイプレベルの操作の恩恵を受けます。さらに、構造型付けにより、異なる作成者は、共有する(名目上の)型を定義する共通のコンポーネントに強く依存することなく、互換性のある型を持つことができます。オブジェクトは、たとえば入出力コンポーネントの標準化に使用されてきました。
これの珍しいことではない、非常に単純なユースケースは、多くのパラメーターを持つ型を表す慣用的な方法です。書く代わりに:
type ('name, 'addr, 'job, 'id) person = ....
val me : (string, string, Job.t, Big_int.big_int) person
オブジェクトタイプを構造的な「タイプレベルのレコード」として使用して、代わりに次のように書き込むことができます。
type 'a person = .... constraint 'a = < name:'n; addr:'a; job:'j; id:'i >
val me : < name:string; addr:string; job:Job.t; id:Big_int.big_int > person
ファントムタイプとしてのオブジェクトタイプのより高度な使用法については、 AlecHellerとJesseTovによるShCaml(doc)ライブラリ(文字列入力と互換性のあるシェルコマンドを表すために使用されます)、または独自のMacaqueライブラリ(docおよびapi doc)。オブジェクトタイプを使用してSQL値(null可能性情報を含む)とテーブル行タイプを表します。
ポリモーフィックバリアント(OCaml型システムのもう1つの高度な機能。一言で言えば、オブジェクトとレコードの関係は、ポリモーフィックバリアントと代数和型の関係と同じです)。たとえば、この単純な例では、ファントム型としても使用されています。リチャードジョーンズによって、またはOcsigenフレームワークでHTMLドキュメントの有効性をチェックするため。
ただし、これらの高度なタイプのハッカーにはかなりの複雑さのコストがかかることに注意してください。それらを使用する前に、それらがもたらす追加の表現度と静的な安全性と慎重にバランスを取る必要があります。
まとめ
基本的な前提として、オブジェクトをまったく使用しないで安全です。デフォルトではなく、何かが足りないと感じた場合にのみ、それらをデザインに導入する必要があります
オブジェクトは、オープンな再帰/継承に便利です。デフォルト/退屈なケースですでに定義されている動作を改良します。
構造型の型付けは、一連の機能/容量を個別に提供する値を推論する場合に役立つことがあります。