如何在OCaml中解释这个GADT错误?
对不起,这里的问题是“我遗漏了什么”,但我只是遗漏了一些东西 我试图理解GADT如何在OCaml中工作,我定义了以下内容(在如何在OCaml中解释这个GADT错误?,ocaml,gadt,Ocaml,Gadt,对不起,这里的问题是“我遗漏了什么”,但我只是遗漏了一些东西 我试图理解GADT如何在OCaml中工作,我定义了以下内容(在utop): 我定义了一个eval函数: let rec eval : type a. a expr -> a = function | Value (Int i) -> i | Value (Bool b) -> b | Lt (a, b) -> (eval a) < (eval b) | Gt (a, b) -> (eval a) &
utop
):
我定义了一个eval
函数:
let rec eval : type a. a expr -> a = function
| Value (Int i) -> i
| Value (Bool b) -> b
| Lt (a, b) -> (eval a) < (eval b)
| Gt (a, b) -> (eval a) > (eval b)
| Eq (a, b) -> (eval a) = (eval b)
| If (c, a, b) -> if eval c then (eval a) else (eval b)
;;
这到底是什么意思?
为了进一步测试,我将表达式GADT修改为:
type _ expr =
| Value : 'a value -> 'a expr
| If : bool expr * 'a expr * 'a expr -> 'a expr
| Lt : int expr * int expr -> bool expr
| Eq : 'a expr * 'a expr -> bool expr
| Gt : int expr * int expr -> bool expr
;;
然后我明白了
Line 6, characters 15-23:
Error: This expression has type $Eq_'a but an expression was expected of type
int
当我最终将其修改为
type _ expr =
| Value : 'a value -> 'a expr
| If : bool expr * 'a expr * 'a expr -> 'a expr
| Lt : int expr * int expr -> bool expr
| Eq : int expr * int expr -> bool expr
| Gt : int expr * int expr -> bool expr
;;
它很好用
更新(更多上下文):
- Ocaml版本:
4.08.1
- 在此会话期间打开的库:
Base
- 结果是(如所选答案的第一行所述),因为我以前在
runutop
openbase代码>
- 在新的会话中,我能够输入最初提到的类型,
对此感到满意eval
),并用整数比较运算符替换它们
关于错误消息,当您将GADT构造函数与存在类型进行模式匹配时
| Lt (a, b) -> (eval a) < (eval b)
存在一个量化类型变量:'a
在Lt
上进行模式匹配时,需要将此类型变量替换为
一种新型的。此外,在错误消息中,尝试拾取是非常有用的
此类型的有意义名称。为此,typechecker构造一个
新类型的名称为$
+Lt
+'a
:
:标记存在类型$
:表示它是由构造函数引入的Lt
Lt
:记住存在类型变量在构造函数的定义中被命名为a
'a
| Lt ( (a: $Lt_'a eval), (b: $Lt_'a eval)) -> (eval a) < (eval b)
该错误的直接原因是您使用的库(可能是Base或Core?)对多态比较运算符(
)进行了阴影处理,并将其替换为整数比较运算符
关于错误消息,当您将GADT构造函数与存在类型进行模式匹配时
| Lt (a, b) -> (eval a) < (eval b)
存在一个量化类型变量:'a
在Lt
上进行模式匹配时,需要将此类型变量替换为
一种新型的。此外,在错误消息中,尝试拾取是非常有用的
此类型的有意义名称。为此,typechecker构造一个
新类型的名称为$
+Lt
+'a
:
:标记存在类型$
:表示它是由构造函数引入的Lt
Lt
:记住存在类型变量在构造函数的定义中被命名为a
'a
| Lt ( (a: $Lt_'a eval), (b: $Lt_'a eval)) -> (eval a) < (eval b)
等等,这是因为我在评估中使用了
,=
,并且这些限制为int
?我无法在4.02.3或4.08.1上复制。您使用的是哪个版本?等等,这是因为我在评估中使用了
,=
,并且这些限制为int
?我无法在4.02.3或4.08.1上复制。你是哪个版本的?
| Lt ( (a: $Lt_'a eval), (b: $Lt_'a eval)) -> (eval a) < (eval b)
(eval a) < (eval b)
Line 4, characters 15-23:
Error: This expression has type $Lt_'a but an expression was expected of type
int