ocaml多态性--强迫一个类型与一个多态类型相顺应。

问题描述 投票:0回答:2

我想做一个简单的层次参数多态类型,当我尝试应用它时,会出现一个错误的类型错误。

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

有谁能建议我如何将这两种类型联系起来?

polymorphism ocaml
2个回答
1
投票

它真的不清楚什么是类型 '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

这个版本创建了一个漏斗,它可以从一个节点型创建同构但不兼容的节点型。


1
投票

你的签名为 H 定义 H.value 作为一个抽象类型。所以,唯一可以是这种类型的OCaml值是由函数在 H. 然而,在 H 类型的东西,返回 H.value.

出于这个原因,它不可能调用 H.hierarchy. 实质上,你已经定义了一个没有可用接口的模块。

© www.soinside.com 2019 - 2024. All rights reserved.