Types 带有函子和多态变量的OCaml类型检查问题

Types 带有函子和多态变量的OCaml类型检查问题,types,module,functional-programming,pattern-matching,ocaml,Types,Module,Functional Programming,Pattern Matching,Ocaml,我在OCaml中使用函子时遇到问题。我有一个模块类型TASK,用于执行不同类型的任务: module type TASK = sig type task_information type task_information_as_lists type abstract_u_set_type module AbstractUSet : Set.S with type t = abstract_u_set_type val mk_task_information : task_

我在OCaml中使用函子时遇到问题。我有一个模块类型
TASK
,用于执行不同类型的任务:

module type TASK = sig
  type task_information
  type task_information_as_lists

  type abstract_u_set_type
  module AbstractUSet : Set.S with type t = abstract_u_set_type

  val mk_task_information : task_information_as_lists -> task_information
end
TASK
类型的模块将包含使用节点的算法。这些节点将具有不同的类型。因此,我构建了任务节点:

module type TASK_NODE = sig
  type t
  val compare : t -> t -> int
  val to_string : t -> string
end
来自
任务
任务
列表中的
任务信息将是一个包含不同类型的列表,但每个任务在该列表中都有不同的类型。由于我不能使用类似于函数的
模块游戏:(任务类型为u:=int list)
,我已经创建了一个模块类型
INFO\u载体
。对于每种不同类型的
TASK
模块,我希望有一个不同类型的
INFO\u CARRIER
模块,该模块将保存所列的
TASK\u信息类型的信息

这是模块类型
信息载体

module type INFO_CARRIER = sig
  module INODE : TASK_NODE
  type u = [`V of INODE.t list | `E of INODE.t] list
end
对于测试,我希望有
string
TASK\u节点
,以及一个
INFO\u载体
,它可以传递一个类型u,比如
类型u=[`V of string list |`E of string]list

因此,我构建了
StringTaskNode
StringInfoCarrier
,以及一个
StringTask
来使用这些节点:

module StringTaskNode : TASK_NODE = struct
  type t = string
  let compare = compare
  let to_string s = "Node " ^ s
end

module StringInfoCarrier (TN : TASK_NODE) : (INFO_CARRIER with module INODE = TN) = struct
  module INODE = TN
  type u = [`V of TN.t list | `E of TN.t] list
end

module StringTask (TN : TASK_NODE) (IC : INFO_CARRIER with module INODE = TN) : 
  (TASK with type task_information_as_lists := IC.u with type abstract_u_set_type := Set.Make(IC.INODE).t) = struct
  module N = IC.INODE
  module AbstractUSet = Set.Make(IC.INODE)

  type task_information = {v_nodes : AbstractUSet.t ; e_nodes : N.t}

  let mk_task_information info_list =
    match info_list with
    | (`V v)::(`E e)::[] -> {v_nodes = AbstractUSet.of_list v ; e_nodes = e;}
    | _ -> raise .... (* raising an error here *)
end
然后,我有另一个模块
ProdFP
,它将为一个任务执行一些计算:

module ProdFP 
  (TN : TASK_NODE) 
  (IC : INFO_CARRIER with module INODE=TN) 
  (TA : TASK with type abstract_u_set_type:=u with type task_information_as_lists:=IC.u) = struct
  ...
end
到目前为止,没有发生错误。但当我在
Test
中将所有内容组合在一起时,我得到:

Error: This expression has type
  [`E of string | `V of string list]
but an expression was expected of type
SIC.u = [`E of SIC.INODE.t | `V of SIC.INODE.t list]
Type string is not compatible with type
  SIC.INODE.t = STN.t
这是测试模块:

module Test = struct
  module STN = StringTaskNode
  module SIC = StringInfoCarrier(STN)
  module ST = StringTask(STN)(SIC)
  module PF = ProdFP(STN)(SIC)(ST)

  let v_list =["a";"b"]
  let e = "c"
  let info_as_list = [`V v_list ; `E e]

  let info = ST.mk_task_information info_as_list (* THIS IS WHERE THE ERROR HAPPENS *)
end
我知道,这是一篇很长的文章,但我已经尝试包含尽可能多的必要信息。
如果您能帮助我,那就太好了:)

看起来问题只是
StringTaskNode
模块定义中的签名约束:

模块StringTaskNode:TASK\u NODE=struct
...
结束
此约束使类型
StringTaskNode.t
抽象,从而隐藏等式
STN.t=string
。移除约束

模块StringTaskNode=struct
...
结束

应该解决这个具体问题。

Wow!非常感谢你的解释——既然你这么说了,很明显:)