В настоящее время я пытаюсь реализовать алгоритм вывода типов (алгоритм унификации) с использованием языка 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) **)
Любые отзывы приветствуются.Спасибо.