6

この ocaml スニペットがトップレベルで適切に型付けされているのは非常に奇妙です。構造体を見てください。トップレベルに示されているように g が int->int 型の場合、構造体のh x = g x一部は型を統一できません。それで、誰でも少し明確にすることができますか?

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

これはトップレベルの応答です:

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

2 に答える 2

8

ここで理解しておくべき重要なことは、OCaml は構成的な方法で型推論を実行するということです。つまり、最初に の型を推論し、struct ... end次に推論された型sig ... endを照合して、構造が実際に署名を実装しているかどうかを検証します。

たとえば、次のように書くと

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

OCaml は、必要な型に特化できるf多相型を持っていることがわかるので、満足します。は不透明にするため、つまりシグネチャは実装を隠すため、実際の実装には多相型があっても、それが typeであることがわかります。'a -> 'aint -> intsig ... endMonkeyfint -> int

あなたの特定のケースでは、OCaml は最初gに type を持っていると推測し'a -> 'a、次に type も同様であるとh推測'a -> 'aします。したがって、構造体には型があると結論付けられます

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

次に、署名が指定されたものと照合されます。型の関数は'a -> 'a特殊化できるためint -> intstring -> stringOCaml はすべてがうまくいっていると結論付けます。もちろん、使用の要点はsig ... end、構造を不透明にする (実装を非表示にする) ことです。これが、トップレベルがandのポリモーフィック型を公開しない理由です。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
于 2012-06-19T21:03:19.463 に答える
8

モジュールからエクスポートされるまで、string -> stringタイピングは適用されないと思います。gモジュールの内部には (型を指定していないため) type があり 'a -> 'aます。(免責事項:私はモジュールの専門家ではありませんが、学びたいと思っています。)

于 2012-06-19T17:01:37.923 に答える