2013-03-28 24 views
12

OCamlのHindley-Milner型システムでは、レコード型の多少の拡張を除いては、impredicative polymorphism(System-F)は使用できません。 F#も同様です。F#の記述型多型

しかし、忠実な多型(例えば、Coq)を用いて記述されたプログラムをそのような言語に翻訳することが時には望ましい。 OCamlへのCoqの抽出プログラムの解決策は、普遍的な安全でないキャストの一種であるObj.magicを(控えめに)使用することです。 OCamlでのランタイムシステムにおける

  • は、すべての値が
  • 元のプログラムに適用され、より洗練されたタイプのシステム
  • は、安全性を入力する保証(32ビットまたは64ビットのアーキテクチャに応じて)にかかわらず、その種類の同じ大きさを持っているので、これは動作します。

F#で同様のことをすることはできますか?

+2

それらが導入されたとして、ポリモーフィックレコードのフィールドは、ほとんどの基準では「最近」ではありません2002年には3.05であった。 – gasche

+1

"impredicative polymorphism"の意味はCoqの文脈では異なっていることに言及する価値があります。 Coqは、型変数を多態型でインスタンス化することを許可しますが、通常、値がボックス化されている場合でも、それをいつ実行できるかに制限があります。これは、論理的な一貫性を保証するために行われます。 OCamlとHaskell側では、 "impredicative"と呼ばれているのは、タイプ変数に* unboxed *(つまりレコードではない)多型を代入できることだけです。したがって、上位ランクの型をより便利にする方法です。 –

答えて

10

達成したいことを具体的に説明することができれば助かります。 (このようなHaskellウィキからthis exampleなど)いくつかのimpredicativeの用途は、単一の汎用的な方法では、追加の公称タイプを使用してエンコードするのが比較的容易である:

type IForallList = 
    abstract Apply : 'a list -> 'a list 

let f = function 
| Some(g : IForallList) -> Some(g.Apply [3], g.Apply ("hello" |> Seq.toList)) 
| None -> None 

let rev = { new IForallList with member __.Apply(l) = List.rev l } 

let result = f (Some rev) 
+2

私は数ヶ月前に書いた別の例です:https://gist.github.com/mausch/3895976 –

+0

OCamlでは 'type forall_list = {apply: 'a。 'リスト - >'リスト} 'と' let rev = {apply = List.rev} 'を実行します。 – didierc

+1

はい、これは私が言及したレコードタイプ(レコードフィールドには普遍的なタイプがあるかもしれません)の幾分最近の拡張です。 –