2013-03-28 12 views
12

Das Hindley-Milner-System von OCaml erlaubt keine imprädikative Polymorphie (à la System-F), außer durch eine etwas jüngere Erweiterung für Datensatztypen. Gleiches gilt für F #.Imprädikativer Polymorphismus in F #

Es ist jedoch manchmal wünschenswert, mit imprädikativem Polymorphismus (z.B. Coq) geschriebene Programme in solche Sprachen zu übersetzen. Die Lösung für Coq's Extractor zu OCaml ist, (sparsam) Obj.magic zu verwenden, das eine Art universellen unsicheren Cast ist. Dies funktioniert, weil

  • in OCaml der Runtime-System, alle Werte die gleiche Größe, unabhängig von ihrer Art haben (32 oder 64 Bit je nach Architektur)
  • des anspruchsvolleren Art System zu dem ursprünglichen Programm angewandt garantiert Sicherheit geben.

Ist es möglich, etwas ähnliches in F # zu tun?

+2

Polymorphe Satzfelder werden nicht als „jüngste“ von den meisten Standards, wie sie eingeführt wurden im Jahr 2002 für 3,05. – gasche

+1

Es ist erwähnenswert, dass die Bedeutung von "impredicative Polymorphism" im Zusammenhang mit Coq. Coq erlaubt es, eine Typvariable mit einem polymorphen Typ zu instanziieren, aber normalerweise gibt es Einschränkungen, wann dies möglich ist, selbst wenn der Wert eingerahmt ist. Dies geschieht, um die logische Konsistenz zu gewährleisten. Auf der OCaml- und Haskell-Seite ist das, was "impredicative" genannt wird, einfach in der Lage, einen * unboxed * (d.h. nicht aufzeichnenden) polymorphen Typ für eine Typvariable zu ersetzen. Somit ist es nur ein Weg, um höherrangige Typen bequemer zu machen. –

Antwort

10

Es wäre hilfreich, wenn Sie genauer erläutern könnten, was Sie erreichen möchten. Einige imprädikative Anwendungen (wie this example vom Haskell wiki) sind relativ einfach einen zusätzlichen Nenn Typen mit einer einzigen generischen Methode zum Codieren mit:

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

Hier ist ein anderes Beispiel, das ich vor ein paar Monaten geschrieben habe: https://gist.github.com/mausch/3895976 –

+0

Dasselbe kann auch in OCaml mit einem Datensatz wie 'type forall_list = {apply: 'a gemacht werden. 'eine Liste ->' eine Liste} 'und' let rev = {apply = List.rev} '. – didierc

+1

Ja, dies ist die etwas neue Erweiterung für Datensatztypen, die ich erwähnt habe (Datensatzfelder können universelle Typen haben). –