ここで重要なことは、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 ... end
はMonkey
を不透明にします。つまり、シグネチャが実装を隠すため、実際の実装に多態型があるにもかかわらず、のf
があります。
あなたの特定のケースではOCamlのは、最初のg
がh
のタイプは、同様'a -> 'a
であること、その後'a -> 'a
を入力して、持っていることを推測します。したがって、構造体には型があると結論づけます。
sig val g : 'a -> 'a val h : 'a -> 'a end
次に、署名は指定されたものと照合されます。タイプ'a -> 'a
のファンクションはint -> int
と同様にstring -> string
に特化することができるため、OCamlはすべてが良好であると結論付けます。もちろん、sig ... end
の使用のポイントは、構造が不透明(実装が隠されている)にすることです。これは、トップレベルがではなく、g
とh
の多型を公開するではありません。ここで
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
です。 – gasche
優秀、ありがとう! :-) –