Непосредственной причиной ошибки является то, что вы используете библиотеку (может быть, Base или Core?), Которая скрывает полиморфные операторы сравнения (<
, <=
, =
, >=
, >
)и замените их целочисленными операторами сравнения.
Что касается сообщения об ошибке, когда вы сопоставляете шаблон с конструктором GADT с экзистенциальными типами,
| Lt (a, b) -> (eval a) < (eval b)
, средство проверки типов вводит новые типы для представления экзистенциальных типов.Здесь в (оригинальном) определении Lt
,
| Lt : 'a expr * 'a expr -> bool expr
есть одна экзистенциально квантифицированная переменная типа: 'a
.
При сопоставлении с образцом на Lt
нам нужнозаменить эту переменную типа новым типом.Более того, в сообщении об ошибке весьма полезно попытаться выбрать значимое имя для этого типа.Для этого средство проверки типов создает поэлементно новое имя типа как $
+ Lt
+ 'a
:
$
: чтобы отметить экзистенциальный тип Lt
: указать, что он был введен конструктором Lt
a
: запомнить, что переменная экзистенциального типа была названа 'a
в определении конструктора
Другими словами, в приведенном выше шаблонном сопоставлении мы имеем что-то похожее на
| Lt ( (a: $Lt_'a eval), (b: $Lt_'a eval)) -> (eval a) < (eval b)
И при наборе:
(eval a) < (eval b)
проверка типов сравнивает тип <
: int -> int
с типом eval a
: $Lt_'a
и выводит исходное сообщение об ошибке:
Line 4, characters 15-23:
Error: This expression has type $Lt_'a but an expression was expected of type
int