It is important to understand that OCaml performs type inference in a compositional style, that is, it first displays the type struct ... end, and only then will it match against the output types sig ... endto make sure that the structure really implements the signature.
For example, if you write
module Monkey : sig val f : int -> int end =
struct
let f x = x
end
OCaml , , f 'a -> 'a, int -> int. sig ... end Monkey, .. , , f int -> int, .
OCaml , g 'a -> 'a, h '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