OCaml检查元素是否在元组的右侧

时间:2018-12-10 10:09:34

标签: list tuples ocaml type-inference

我目前正在尝试使用OCaml语言实现类型推断算法(统一算法)。我遇到了一些实施方面的困难,希望有人能给予我一些帮助。


让我提供一些我要实现的背景信息。

[(TypeVar "t1", TypeFunc (TypeVar "t2", TypeVar "t3"))]

(type * type) list类型是表达等式的一种方式,例如将类型t1映射到t2 -> t3的函数。

我要捕获的是等式左侧的类型变量也出现在右侧的情况,这将导致算法失败。详细说明,如果可以的话

[(TypeVar "t1", TypeFunc (TypeVar "t1", TypeVar "t3"))]

这会给我们带来一个错误,因为t1 = t1 -> t3是一个矛盾。


这是我为解决这一矛盾而尝试实现的实际OCaml函数:

let contradiction_check (a, t) =
  List.exists (fun (x, _) -> x = a) t;;

let t1 = TypeVar "t1";;
let t2 = TypeFunc (TypeVar "t2", TypeVar "t3");;

此代码的问题是,首先t2不是列表,这会给我们带来错误。但是,这是有意的,因为我的目标是获取元组列表[(TypeVar "t1", TypeFunc (TypeVar "t2", TypeVar "t3"))]并检查元组的左侧是否出现在右侧。

我想我的具体问题是:是否可以将List.exists函数实现为元组的版本?我已经尝试过手动编写函数,但是它似乎比我最初想象的要复杂。

例如:

[(TypeVar "t1", TypeFunc (TypeFunc (TypeVar "t2", TypeVar "t3"),
  TypeFunc (TypeVar "t1", TypeVar "t4")))]

(** t1 = (t2 -> t3) -> (t1 -> t4) **)


任何反馈都值得赞赏。谢谢。

1 个答案:

答案 0 :(得分:0)

您应该只编写一个递归函数进行搜索:

No operations defined in spec!

我不知道您的情况如何,但是您将编写类似上面的函数。

然后查看您是否可以统一事物:

(** [is_free ~varname t] is [true] iff [varname] appears as a free type variable in [t] *)
let is_free ~varname =
  let rec r = function
    | TypeVar n when String.( = ) n varname -> true
    | TypeVar _ -> false
    | TypeFunc s t -> r s || r t
    | TypaApp c t -> r c || r t (* if c is just a name not a type you don’t want [r c] here *)
    | TypeForall n t -> 
      if String.( = ) n varname
      then false
      else r t
  in
  r

您现在可以通过熟悉的列表功能实现所需的功能。