gpt4 book ai didi

rust - Rust 如何为 Hindley-Milner 解决可变性问题?

转载 作者:行者123 更新时间:2023-11-29 07:52:25 25 4
gpt4 key购买 nike

我读到 Rust 使用 Hindley-Milner 有很好的类型推断。 Rust 也有可变变量,据我所知,当 HM 算法处理可变性时必须有一些约束,因为它可能过度泛化。以下代码:

let mut a;
a = 3;
a = 2.5;

不编译,因为在第二行推断出整数并且不能将浮点值分配给整数变量。所以我猜测对于简单变量,一旦推断出非泛型类型,变量就会变成单一类型,不能再泛化。

但是像 Vec 这样的模板呢?例如这段代码:

let mut v;
v = Vec::new();
v.push(3);
v.push(2.3);

这又失败了,但是最后一行又失败了。这意味着第二行部分推断出类型 (Vec),第三行推断出容器类型。

规则是什么?是否有我不知道的值限制之类的东西?还是我让事情过于复杂,而 Rust 有更严格的规则(比如根本没有泛化)?

最佳答案

rustc 在其类型推断中过于急切被认为是一个问题(就诊断质量而言)。

如果我们检查您的第一个示例:

let mut a = 3;
a = 2.5;

然后第一行导致推断a有一个 {generic integer type} ,第二行将导致诊断 2.5不能分配给 a因为它不是通用整数类型。

预计更好的算法会记录冲突,然后指向每种类型的来源。也许我们会用 Chalk 得到它.

注意:通用整数类型是 Rust 使整数文字“多态”的技巧,如果没有其他提示它应该是什么特定整数类型,它将默认为 i32 .


第二个例子的发生方式基本相同。

let mut v = Vec::new();
v.push(3);

详细信息:

  • v分配类型 $T
  • Vec::new()生产类型 Vec<$U>
  • 3生产类型 {integer}

因此,在第一行,我们得到 $T == Vec<$U>在第二行我们得到 $U == {integer} , 所以 v推导出类型为 Vec<{integer}> .

如果没有其他来源可以了解确切的整数类型,则返回到 i32默认情况下。


我想指出,可变性实际上并不影响这里的推理;从类型推断或类型统一的角度来看,以下代码示例是等效的:

//  With mutability:
let mut a = 1;
a = 2.5;

// Without mutability:
let a = if <condition> { 1 } else { 2.5 };

Rust 在 HM 方面存在更严重的问题,Deref子类型变得更具挑战性。

关于rust - Rust 如何为 Hindley-Milner 解决可变性问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43886963/

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