2012-06-19 12 views
5

このocamlスニペットがトップレベルによってよくタイプされているのはかなり奇妙です。構造体を見てください.gがトップレベルに示すようにint-> int型の場合、構造体のh x = g x部分は型統一されません。だから誰も少し明確にすることができますか? Ocamlでの入力の奇妙な例

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

この

はtopelevelの応答です:

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

答えて

7

ここで重要なことは、OCamlは型推論を構成的な方法で実行することです。つまり、最初にstruct ... endの型を推論します。推定された型をsig ... endと照合して、構造体が実際に署名を実装していることを検証します。例えば

あなたは

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

を書くならば、それはfが必要なタイプint -> intに特化したことができるポリモーフィック型の'a -> 'aを持っていることがわかりますように、そしてOCamlでは、幸せになります。 sig ... endMonkeyを不透明にします。つまり、シグネチャが実装を隠すため、実際の実装に多態型があるにもかかわらず、のfがあります。

あなたの特定のケースではOCamlのは、最初のghのタイプは、同様'a -> 'aであること、その後'a -> 'aを入力して、持っていることを推測します。したがって、構造体には型があると結論づけます。

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

次に、署名は指定されたものと照合されます。タイプ'a -> 'aのファンクションはint -> intと同様にstring -> stringに特化することができるため、OCamlはすべてが良好であると結論付けます。もちろん、sig ... endの使用のポイントは、構造が不透明(実装が隠されている)にすることです。これは、トップレベルがではなく、ghの多型を公開するではありません。ここで

OCamlはどのように機能するかを示す別の例である:

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 

応答は、あなたの答えは完全に正しい

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

それがモジュールから 輸出されるまで、私はstring -> stringタイピングがgに適用されていないことを言うと思います。モジュールの中に(型を与えていないので)、型は 'a -> 'aです。 (免責:私はモジュールの専門家ではなく、学ぶことを試みています)

+0

です。 – gasche

+0

優秀、ありがとう! :-) –