簡體   English   中英

為什么F#泛型類型推斷在構造函數上有所不同?

[英]Why is F# generic type inference different on constructors?

這種情況(簡化到沒有多大意義)由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,因此可以使用兩個不同的參數調用它。

現在,以下版本略有不同:它不是將creature作為參數傳遞給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)

(注意:在這個簡化的情況下,Factory顯然有缺陷,因為它總是返回相同的animal / humanBeing,但是如果用函數替換anAnimal / aHuman,這種行為不會改變。)

為什么在第二種情況下CreatureControlled不是通用的? 這是編譯器限制嗎? 我錯過了一些非常基本的東西(還在學習......)?

在第一種情況下,正如您所說, Register被推斷為通用的,因此它有效。 在第二種情況下,您將兩種不同的類型傳遞給非泛型類的構造函數。 在這種情況下必須推斷出具體類型。 如果你將類型args添加到生物控制器,它可以工作:

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

區別在於類型參數必須在類型上是顯式的,而不是在函數上。 此外,構造函數只能處理類型本身聲明的類型參數。

在構造函數的情況下,你可能(或至少是模棱兩可的)你認為類型本身是通用的,例如

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

在F#中,必須始終明確指定類型定義的泛型參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM