gpt4 book ai didi

types - 存在量化类型参数、递归函数和类型错误

转载 作者:行者123 更新时间:2023-12-01 19:47:56 27 4
gpt4 key购买 nike

考虑以下 OCaml 代码:

type mytype = My : 'a list * 'a -> mytype

let rec foo : int -> mytype =
fun n -> if n < 0 then My([], 2)
else let My(xs, y) = foo (n - 1)
in My(3::xs, y)

OCaml 解释器在 foo 的最后一行给我一个错误,说:

This expression has type a#1 list but an expression was expected of type int list

Type a#1 is not compatible with type int

我可以通过向 mytype 添加一个类型参数来使该代码正常工作,这样就可以了

type _ mytype = My : 'a list * 'a -> 'a mytype
let rec foo : int -> 'a mytype =
...

但假设我真的不想更改 mytype 的定义。假设我想保留该函数的(通过非工作代码直观地理解)行为,我可以编写 foo 吗?

另外,有人可以解释问题的根源是什么,即为什么初始代码不进行类型检查?

最佳答案

当对 mytype 值进行模式匹配时,无法知道其中的类型。问题是,打字系统的行为非常简单,并且不会尝试知道 mytype 来自哪里,即使它来自递归调用(打字系统只是不那样工作)。

问题是,在这种情况下,您知道 'a 确实是 int,但您需要向编译器提供证明。

在这种特定情况下,您不需要这样做。您只需要在函数末尾使用 GADT:

let foo n =
let rec aux n =
if n < 0 then ([], 2)
else let (xs, y) = aux (n - 1)
in (3::xs, y)
in
let (xs,y) = aux n in My (xs,y)

值得注意的是,通过该类型定义,您无法使用您知道 mytype 中存在整数值的事实,因此它将非常无法使用。 GADT 应该仅在特定情况下使用,并且您应该准确地知道为什么以及如何使用它们。

编辑:

类型可以被视为附加到每个值的逻辑公式。在大多数情况下,它非常简单,您不必担心,主要是因为类型变量('a 'b 等)是普遍量化并且对于类型的外部始终可见。

type 'a mylist = Cons of 'a * 'a list | Nil
(* should be read as:
for all 'a,
'a mylist is either
* a cons containing the same 'a and 'a list
* nil *)

type mylist = Cons : 'a * mylist -> mylist | Nil : mylist
(* should be read as:
mylist is either
* for some 'a, a 'a and another list
* nil *)

在上面的 GADT 中,您可以看到没有任何内容表明列表中的每个元素都具有相同类型。事实上,如果你得到一个 mylist,你无法知道里面有什么元素。

所以,您需要证明。这样做的一个好方法是在 gadt 中存储类型证明:

type _ proof =
| Int : int proof
| Float : float proof
| Tuple : 'a proof * 'b proof -> ('a * 'b) proof
(* You can add other constructors depending on
the types you want to store *)

type mytype = My : 'a proof * 'a list * 'a -> mytype

现在有了这个,当打开 mytype 时,您可以匹配证明来证明 'a 的值。编译器会知道它是相同的,因为如果没有与正确类型相对应的证明,它会拒绝创建 mytype。

正如您所看到的,GADT 并不简单,您通常需要在实现之前起草多个草案。大多数时候,您可以避免使用它们(如果您不确定它们是如何工作的,则根本不要使用它们)。

关于types - 存在量化类型参数、递归函数和类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29637591/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com