Ocaml

2012-06-19 22 views
5

yazarak garip bir örnek yazmak, bu ocaml snippet'inin üst seviye tarafından iyi yazılmasından oldukça gariptir. Yapıya bakılırsa, g üst düzeyde gösterildiği gibi int türünde ise, yapının h x = g x bölümü tip-birleştirilmiş olamaz. Yani herhangi biri biraz açıklayabilir mi? Ocaml

module Mymodule : sig 
    val h:int ->int 
    val g: string-> string 
end = struct 
    let g x = x 
    let h x = g x 
end 

Bu

topelevel en yanıttır:

module Mymodule : sig val h : int -> int val g : string -> string end 

cevap

7

Burada anlaşılması gereken önemli nokta, OCaml'ın bir bileşke şeklinde bir tür çıkarsama gerçekleştirmesidir, yani, ilk olarak struct ... end türünü türetir ve Yapının gerçekten imzayı gerçekleştirdiğini doğrulamak için türetilmiş türlerini sig ... end karşı eşleştirecektir. Eğer f gerekli tip int -> int için uzmanlaşmış edilebilir bir polimorfik tipi 'a -> 'a sahip olduğunu göreceğiniz gibi

module Monkey : sig val f : int -> int end = 
struct 
    let f x = x 
end 

sonra OCaml, mutlu olacak yazarsanız Örneğin

. sig ... end, Monkey opak olduğundan, yani imzanın uygulanmasını gizlediği için, gerçek uygulamanın bir polimorfik türüne sahip olmasına rağmen f'un int -> int türünde olduğunu söyleyecektir. sizin özel durumda OCaml ise

ilk g'a -> 'a tip vardır infers ve sonra h türü de 'a -> 'a olduğunu. Bu yüzden yapı tipini

sig val g : 'a -> 'a val h : 'a -> 'a end 

Sonraki olmadığı sonucuna vardı, imza verilmiş birine karşı eşleştirilir. 'a -> 'a türünün bir işlevi int -> int ile string -> string OCaml arasında uzmanlaşabileceğinden, her şeyin iyi olduğu sonucuna varır. Tabii ki, sig ... end kullanarak tüm nokta yapısını opak (uygulama gizli) yapmaktır, bu nedenle üst düzey değil, g ve h polimorfik türünü ortaya çıkarır. İşte

OCaml nasıl çalıştığını gösteren bir başka örnektir:

module Cow = 
struct 
    let f x = x 
    let g x = f [x] 
    let a = f "hi" 
end 

module Bull : sig 
    val f : int -> int 
    val g : 'b * 'c -> ('b * 'c) list 
    val a : string 
end = Cow 

tepki

module Cow : 
    sig 
     val f : 'a -> 'a 
     val g : 'a -> 'a list 
     val a : string 
    end 

module Bull : 
    sig 
     val f : int -> int 
     val g : 'a * 'b -> ('a * 'b) list 
     val a : string end 
    end 
8

o modülünden ihraç edilene kadar ben string -> string yazarak g uygulanan olmadığını söyleyebilirim. Modül içinde (bir tür vermezseniz), 'a -> 'a türüne sahiptir. (Feragatname: Ben bir modül uzmanı değilim, ancak öğrenmeye çalışıyorum.)

+0

Cevabınız mükemmel doğru olmasıdır. – gasche

+0

Mükemmel, teşekkürler! :-) –