Я внедряю добрую систему для нового функционального языка программирования, и в настоящее время я пишу функцию для объединения двух видов. Рассмотрим четыре случая:
+---------+---------+-------------------------------------------------------+
| k1 | k2 | action |
+=========+=========+=======================================================+
| var | var | k1 := k2 ^ k2 := k1 |
+---------+---------+-------------------------------------------------------+
| var | non var | if (!occurs(k1, k2)) k1 := k2 |
+---------+---------+-------------------------------------------------------+
| non var | var | if (!occurs(k2, k1)) k2 := k1 |
+---------+---------+-------------------------------------------------------+
| non var | non var | ensure same name and arity, and unify respective args |
+---------+---------+-------------------------------------------------------+
- Когда оба
k1
иk2
являются переменными, они создаются друг с другом. - Когда только
k1
является переменной, тогда она создается вk2
, если ifk1
не встречается вk2
. - Когда только
k2
является переменной, тогда она создается вk1
iffk2
не встречается вk1
. - В противном случае мы проверяем, имеют ли теги
k1
иk2
одно и то же имя и arity и унифицируют их соответствующие аргументы.
Для второго и третьего случаев нам необходимо выполнить проверку на наличие ошибок, чтобы мы не застревали в бесконечном цикле. Однако я сомневаюсь, что программист сможет построить бесконечный вид вообще.
В Haskell легко построить бесконечный тип:
let f x = f
Однако я не смог построить бесконечный вид, как бы я ни старался. Обратите внимание, что я не использовал никаких языковых расширений.
Причина, по которой я спрашиваю об этом, состоит в том, что, если вообще невозможно построить бесконечный вид, я даже не буду пытаться выполнить проверку на наличие видов в моей доброй системе.