OCaml(3.12.1)のモジュール言語を実験しています。モジュールのファンクタとシグネチャを定義しています。ほとんどの例はChapter 2 of the OCaml manualです。私は偶然、つまずきました。明らかに、ファンクターとモジュール署名がどのように機能するかに関する私の精神的モデルには欠陥があります。最短のコードで遭遇した状況を絞り込もうとしました。私が達成しようとしていることを尋ねないでください。これは問題のOCaml機能を実証するための完全に考案された例です。OCaml functors :: counter直感的な振る舞い
そこで、我々は単に恒等関数「F」を提供し、その関数の入力パラメータの種類を供給モジュールによってパラメータ化されたファンクタを持っています。私が言ったような完全に考案された例。
上記のmodule type SOMETYPE = sig type t end ;;
module Identity = functor (Type: SOMETYPE) -> struct let f (x: Type.t) = x end ;;
、我々はint型を供給するためのモジュールを定義するために進ん:
module IntType = struct type t = int end ;;
を...し、その後、我々はint型のアイデンティティ機能のためのモジュールを生成するためにファンクタを使用します。
期待どおりに動作し、十分なmodule IdentityInt = Identity(IntType) ;;
確か生成モジュールとそのf関数:
#IdentityInt.f(3) + 10 ;;
- : int = 13
ファンクタのメンタルモデルは、モジュールを入力およびリターンモジュールとして使用する関数であり、これまでのところ私たちに役立っているようです。 Identity
ファンクタは、入力パラメータとして署名(モジュール型)SOMETYPEのモジュールを想定し、実際に我々は供給モジュール(IntType
)は、そのf
関数期待通りに振る舞う正しい署名を有するので、有効な出力モジュールが製造される(IdentityInt
)。
今直感的ではない部分があります。提供されたモジュールIntType
が確かにSOMETYPEタイプのモジュールであることを明示したい場合はどうでしょうか?その後、
module IntType : SOMETYPE = struct type t = int end ;;
とファンクタの出力モジュールは、前と同じように生成します:同様に
module IdentityInt = Identity(IntType) ;;
...のは、新しく生成されたモジュールのf
機能を使用してみましょう:
IdentityInt.f 0 ;;
この場合、REPLは次のように文句を言います。
"Error: This expression [the value 0] has type int but an expression was expected of type IntType.t."
重複しているが正しいタイプの情報を提供すると、コードが破損することはありますか?ケースAの場合でも、ファンクタモジュールIDはIntType
モジュールをSOMETYPE
タイプとして扱わなければならなかった。では、IntType
をSOMETYPE
型に明示的に宣言すると、どのように異なる結果が得られますか?
2番目の 'module IntType'に' = int'部分がありませんか? – Ptival
いいえ、私のREPLのコピー貼り付けフォームのタイプミスです。 2番目のモジュールIntTypeは正しく読み込まれます: 'module IntType:SOMETYPE = struct type t = int end'そして、上で説明したのとまったく同じ結果を得ます。私はあまりにも誤解を避けるために投稿を編集します。 –