我目前正在尝试使用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) **)
任何反馈都值得赞赏。谢谢。
答案 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
您现在可以通过熟悉的列表功能实现所需的功能。