gpt4 book ai didi

types - 为什么 F# 泛型类型推断在构造函数上不同?

转载 作者:行者123 更新时间:2023-12-01 11:04:25 25 4
gpt4 key购买 nike

这种情况(已简化到没有多大意义)由 F# 的类型系统正确处理:

type HumanBeing() = class end
type Animal() = class end

type CreatureController() =
member this.Register creature = creature

type CreatureFactory() =
let anAnimal = new Animal()
let aHuman = new HumanBeing()

member this.GiveMeAnAnimal =
(new CreatureController()).Register anAnimal

member this.GiveMeAHuman =
(new CreatureController()).Register aHuman

正确推断出 CreatureController.Register 的类型:'a -> 'a,因此可以用两个不同的参数调用它。

现在以下版本略有不同:不是将生物作为参数传递给 CreatureController.Register,而是传递给其构造函数。

type HumanBeing() = class end
type Animal() = class end

type CreatureController(creature) =
member this.Register = creature

type CreatureFactory() =
let anAnimal = new Animal()
let aHuman = new HumanBeing()

member this.GiveMeAnAnimal =
(new CreatureController(anAnimal)).Register

member this.GiveMeAHuman =
(new CreatureController(aHuman)).Register

第二个示例无法编译,因为 Register 被推断为 Animal,因此您不能调用 new CreatureController(aHuman)

(注意:在这个简化的例子中,工厂显然有缺陷,因为它总是返回相同的动物/人类,但如果你用函数替换动物/人类,这种行为不会改变。)

为什么在第二种情况下 CreatureControlled 没有创建为通用的?这是编译器限制吗?我是否遗漏了一些非常基本的东西(仍在学习中......)?

最佳答案

在第一种情况下,如您所述,Register 被推断为通用的,因此它有效。在第二种情况下,您将两种不同的类型传递给非泛型类的构造函数。在这种情况下必须推断具体类型。如果您将类型参数添加到生物 Controller ,它会起作用:

type HumanBeing() = class end
type Animal() = class end

type CreatureController<'T>(creature:'T) =
member this.Register = creature

type CreatureFactory() =
let anAnimal = new Animal()
let aHuman = new HumanBeing()

member this.GiveMeAnAnimal =
(new CreatureController<_>(anAnimal)).Register

member this.GiveMeAHuman =
(new CreatureController<_>(aHuman)).Register

区别在于类型参数在类型上必须是显式的,而在函数上则不能。此外,构造函数可能只处理由类型本身声明的类型参数。

关于types - 为什么 F# 泛型类型推断在构造函数上不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7534240/

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