8

私は OCaml の次のファンクターの問題にかなり悩まされています。理解できるように、コードの一部を貼り付けます。基本的

でこれら 2 つのモジュールを定義しましたpctl.ml

module type ProbPA = sig
  include Hashtbl.HashedType  
  val next: t -> (t * float) list
  val print: t -> float -> unit
end

module type M = sig
  type s  
  val set_error: float -> unit
  val check: s -> formula -> bool
  val check_path: s -> path_formula -> float
  val check_suite: s -> suite -> unit
end

および次のファンクタ:

module Make(P: ProbPA): (M with type s = P.t) = struct
  type s = P.t
  (* implementation *)
end

次に、これらのモジュールを実際に使用するために、次の名前のファイルに新しいモジュールを直接定義しましたprism.ml

type state = value array
type t = state
type value =
  | VBOOL of bool
  | VINT of int
  | VFLOAT of float
  | VUNSET
(* all the functions required *)

3 番目のソース ( ) から、モジュールformulas.mlでファンクターを使用しました。Prism

module PrismPctl = Pctl.Make(Prism)
open PrismPctl

そして最後からmain.ml

open Formulas.PrismPctl
(* code to prepare the object *)
PrismPctl.check_suite s.sys_state suite (* error here *)

そしてコンパイルすると、次のエラーが発生します

エラー: この式にはタイプ Prism.state = Prism.value 配列がありますが、タイプ Formulas.PrismPctl.s の式が予期されていました

私が理解できることから、名前の一種の悪いエイリアシングがあり、それらは同じvalue arrayです(型がとして定義され、ファンクターでt使用さM with type s = P.tれているため)が、型チェッカーはそれらを同じとは見なしません。

どこに問題があるのか​​ 本当にわかりません。誰か助けてもらえますか?

前もって感謝します

4

2 に答える 2

6

(あなたはコンパイルできないコードを投稿します。それは悪い考えです。人々があなたを助けるのを難しくするかもしれませんし、問題を簡単な例に落とし込むだけで解決できる場合もあるためです。しかし、とにかくあなたの難しさを理解していると思います。 )

内部formulas.mlでは、Ocaml はそれを見ることができますPrismPctl.s = Pctl.Make(Prism).t = Prism.t。最初の等号は の定義からのもので、2 番目の等号は(具体的にはビット)PrismPctlの署名からのものです。Pctl.Makewith type s = P.t

mli用のファイルを作成しない場合Formulas、コードはコンパイルされるはずです。したがって、問題は、.mliあなたが書いたファイルが正しい等式について言及していないことであるに違いありません。あなたはあなたのファイルを表示しません.mli(表示すべきです、それらは問題の一部です)が、おそらくあなたが書いた

module PrismPctl : Pctl.M

それだけでは十分ではありません: コンパイラが をコンパイルするとき、コンパイラは で指定されていmain.mlないことについて何も知りません。どちらかを指定する必要がありますPrismPctlformulas.mli

module PrismPctl : Pctl.M with type s = Prism.t

with type s = P.tまたは、の署名に含まれているMakeと仮定しますpctl.mli

module PrismPctl : Pctl.M with type s = Pctl.Make(Prism).s
于 2010-07-25T19:37:32.017 に答える
2

これは、これらについて詳しく学ぶときに私が遭遇した問題でもあります。ファンクターを作成すると、ファンクターのシグネチャー (この場合はM. ファンクターによってパラメーター化された抽象型が含まれており、sより具体的なものは外部に公開されていません。sしたがって、 (のように)の任意のレコード要素にアクセスするsys_stateと、遭遇したように型エラーが発生します。

残りは問題ないようです。ファンクターを適切に使用することは間違いなく困難ですが、ファンクターによって公開されているインターフェイス/シグネチャを介して、ファンクターによってパラメーター化された型のインスタンスのみを操作できることを覚えておいてください。

于 2010-07-25T06:21:29.680 に答える