2015-01-09 12 views
8

私たちはそれを必要とするときにそれを使用する理由のOCamlにGADT の概念の周りを検索したが、私はGADTはOCamlのではなく、より一般的な用語だけではありません理解しています。私は、などOCamlでGADTを実証するための具体的な簡単な例は?</p> <p>など

What are GADTs?

http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc85

http://www.reddit.com/r/ocaml/comments/1jmjwf/explain_me_gadts_like_im_5_or_like_im_an/

を見つけたが、それらのいくつかはHaskellであり、そして他の人がなしGADTの間の良好な比較の例を持っていない

およびGADT

私が望むのは、GADTがないと状況が悪いかどうかを確認できるシンプルで優れた具体的な例です。

どうすればいいですか?

+0

これにより、タイプの制約が厳しくなります。そして、その例は、いくつかのコンストラクタがブール値や整数などでパラメータ化されるかもしれないastです。 – nlucaroni

+1

このような悪い状況はありません.4.0より前には、ocallはガットのサポートを持たず、人々はうまくやっていました。オットー、ガットを持っていることで、特定のことをより簡単に、より効率的にすることができます。 – didierc

+1

私はcamlメーリングリストで2013年初めに起こったガットについての議論も指摘したいと思います。http://lwn.net/Articles/531953/ – didierc

答えて

5

GADTは、2つの理由から有用です。

最初のもの(最も一般的なもの)は動的な型付けに関するものです。動的な型指定を静的なチェックを失うことなく追加できます。それは簡単なことではありませんが、あなたのタイプ条件が満たされることを確信することができます。 その最も簡単な例はocaml manualです。 これは、標準ライブラリでprintfをタイプセーフな方法で書き直すために使用されていました(それ以前はObjのかなり恐ろしいコレクションでした)。マジック)

GADTを使用したいと思う2番目の理由は、タイプ構造を維持したい複雑な不変条件がある場合です。これは表現するのがかなり難しいですし、しばしばそれを行うために多くの努力を払わなければなりません。 まあ、私は便利な例はありませんが、AVL木の実装を書き留めている友人が、タイピングシステムによってバランスがとれていることが証明されていました。

GADTの機能とその優れた使用例については、Mads Hartmannのかなり良いblog postを読むことができます。

+0

例を挙げてください。有り無しの対照のために? –

+0

Mads Hartmannのブログ記事とは別に、標準配布物のPrintfの匿名のコードと新しいコードを検索することができます。 https://github.com/ocaml/ocaml/blob/trunk/stdlib/camlinternalFormatBasics.mlとprintf.mlファイル(同じディレクトリ)を参照し、4.00ブランチと比較してください(GADTフォーマットがここに来る前に)。 – PatJ

+0

'printf'はとても良い例です。 –

3

私はGADTをよく使うアプリケーションを探しています。ほとんどの場合、私はそれらを早くまたは後で使用しても、同じことがそれらがなくても、もっときれいに。だから、これは完全な調査ではなく、ちょっとした自分の経験です。

  1. ユニバーサル値、別名existentials。それらを使用すると、異種のコンテナを作成し、型保証されたシリアル化を行うことができます。例としてコアのUnivUniv_mapモジュールを参照してください。

  2. 構文木のタイプセーフな評価基準。ここでGADTはいくつかのランタイムチェックを削除するのに便利です。

  3. 純正タイプセーフPrintfimplementation、それはすでにOCamlのの一部ですが、またGADT

を使用して書き直されました。ここGADTを使用することができる方法の現実の生活exampleです。この例では、GADTを使用して、表の関係を指定します(例:one_to_oneone_to_manyなど)。使用される関係に応じて、関数のタイプがそれに応じて推測されます。たとえば、one_to_maybe_oneの関係は、関数'a -> 'b optionを返します。one_to_manyは、'a -> 'b listで関数を作成します。 1つの関数link ~one_to:relationではなく、link_one_to_one,link_one_to_manyなどのようないくつかの異なる関数を作成するだけで同じことができます。したがって、このアプローチを議論の余地があると考えることができます。

+0

なぜ同じことができるのか説明してくださいそれらを使わずに、そして通常もっときれいな方法で。それが本当であれば、なぜ4.00がGADTを追加したのですか?また、簡単なデモンストレーションをお願いしますか? –

+2

私はあなたが私を誤解していると思います。 GADTは一般的に役に立たないと主張しているわけではありません。私は、多くの日常業務において、特にそれがないクリーンなソリューションがある場合は、それらを使用すべきではないと主張しています。この文は、ファーストクラスのモジュール、ファンクタ、クラスに拡張できます。しかし、それは彼らが役に立たないということではありません。例えば、普遍的な値(ハッキングなし)はGADTなしでは不可能です。 – ivg

関連する問題