我想做一个简单的层次参数多态类型,当我尝试应用它时,会出现一个错误的类型错误。
module H : sig
type 'a value
type 'a to_value_children = ('a value -> 'a value list option)
type 'a node
val hierarchy: 'a value -> 'a to_value_children -> 'a node
end = struct
type 'a value
type 'a to_value_children = ('a value -> 'a value list option)
type 'a node = {
data: 'a value;
children: 'a node list option;
}
let hierarchy value to_value_children =
let rec build v =
match to_value_children v with
| None -> {data=v; children = None}
| Some c -> (
let node_children =
List.fold_left (fun a c' ->
(build c')::a
) [] c
in
{data=v; children = Some node_children}
)
in
build value
end
type data =
{
name: string;
children: data list option;
}
let data =
{
name = "root";
children = None
}
let to_value_children = fun value -> value.children
let () =
H.hierarchy data to_value_children |> ignore
编译 H.hierarchy data to_value_children
给出以下错误。data: This expression has type data but an expression was expected of type 'a H.value
有谁能建议我如何将这两种类型联系起来?
它真的不清楚什么是类型 'a value
是应该的。目前,它唯一可见的效果是确保模块的 H
是无法使用的。目前的签名是 H
根本没有办法建立任何类型的值。'a value
. 此外,由于 'a value
是模块实现中的一个抽象类型,即使在模块实现中也是如此。如果我猜测,你要么是想写:
module H = struct
type 'a to_value_children = 'a -> 'a list option
type 'a node = {
data: 'a;
children: 'a node list option;
}
let hierarchy value to_value_children =
let rec build data =
let children =
match to_value_children data with
| None -> None
| Some c -> Some (List.map build c) in
{ data; children }
in
build value
end
type data =
{
name: string;
children: data list option;
}
let data =
{
name = "root";
children = None
}
let to_value_children value = value.children
let h =
H.hierarchy data
如果我猜测,你要么是想写: 'a value
根本 hierarchy
可与任何可能的类型一起工作。to_value_children
函数。
或漏斗版本
type 'a to_children = 'a -> 'a list option
module H(Lower: sig type value val to_children: value to_children end) = struct
type 'a node = {
data: 'a;
children: 'a node list option;
}
type value = Lower.value node
let rec hierarchy data =
let children =
match Lower.to_children data with
| None -> None
| Some c -> Some (List.map hierarchy c) in
{ data; children }
let to_children x = x.children
end
...
module Hdata = H(struct
type value = data
let to_children v = v.children
end)
let h1 =
Hdata.hierarchy data
module H2data = H(Hdata)
let h2 = H2data.hierarchy h1
这个版本创建了一个漏斗,它可以从一个节点型创建同构但不兼容的节点型。
你的签名为 H
定义 H.value
作为一个抽象类型。所以,唯一可以是这种类型的OCaml值是由函数在 H
. 然而,在 H
类型的东西,返回 H.value
.
出于这个原因,它不可能调用 H.hierarchy
. 实质上,你已经定义了一个没有可用接口的模块。