ocaml 多态性 - 强制类型符合多态类型
ocaml polymorphism - coercing a type to be complient with a polymorphic type
我正在尝试做一个简单的分层参数多态类型,当我尝试应用它时,会抛出错误的类型错误。
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
谁能建议我如何将这两种类型结合在一起?
您对 H
的签名将 H.value
定义为抽象类型。因此,唯一可以是这种类型的 OCaml 值是由 H
中的函数编辑的值 return。但是,H
中没有 return 类型 H.value
的函数。
因此,无法调用 H.hierarchy
。本质上你已经定义了一个没有可用接口的模块。
实在不清楚'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
此版本创建了一个仿函数,它从类节点类型创建同构但不兼容的类节点类型。
我正在尝试做一个简单的分层参数多态类型,当我尝试应用它时,会抛出错误的类型错误。
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
谁能建议我如何将这两种类型结合在一起?
您对 H
的签名将 H.value
定义为抽象类型。因此,唯一可以是这种类型的 OCaml 值是由 H
中的函数编辑的值 return。但是,H
中没有 return 类型 H.value
的函数。
因此,无法调用 H.hierarchy
。本质上你已经定义了一个没有可用接口的模块。
实在不清楚'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
此版本创建了一个仿函数,它从类节点类型创建同构但不兼容的类节点类型。