2015-04-17 80 views
3

泛型方法這個問題是基於功能隨機生成在這個過程中的一個周:https://www.coursera.org/course/reactiveFSharp調用基類

該課程是基於Scala中,我試圖複製它在FSharp。

這裏是我的問題:

我有一個抽象發電機

[<AbstractClass>] 
type Generator<'a>() = 
    abstract member Generate: 'a 

而且我有一個實現生成隨機整數

type IntGenerator() = 
    inherit Generator<Int32>() 

    let rand = new System.Random() 
    override this.Generate = rand.Next(Int32.MinValue, Int32.MaxValue) 

現在,我想添加地圖方法到我的基類,以便使用這樣的代碼可以創建新類型的生成器

let integers = new IntGenerator()   
let booleans = integers.Map (fun x -> x > 0) 

所以,在這裏就是我修改了基礎類

[<AbstractClass>] 
type Generator<'a>() = 
    abstract member Generate: 'a 
    member this.Map (f:'a -> 'b) = { new Generator<'b>() with member this.Generate = f base.Generate } 

不幸的是,以base.Generate這一呼籲似乎是約束型「B相同的爲」一個

我不得到原因。我確信我正在簡單地做一些事情。

+0

嗨@MaxMalook ...在這種情況下會更復雜 - 因爲'base'不是你想象的那樣) – Carsten

+0

@CarstenKönig,你說得對,它是對象表達式中的'base'類型。 –

回答

3

這裏的問題是,你必須要小心的member方法的實例名稱:

我認爲這應該工作了:

[<AbstractClass>] 
type Generator<'a>() = 
    abstract member Generate: unit -> 'a 
    static member Map (f:'a -> 'b) = 
     fun (g : Generator<'a>) -> 
     { new Generator<'b>() with 
      member this.Generate() = g.Generate() |> f 
     } 

,或者如果你堅持的成員方法:

[<AbstractClass>] 
type Generator<'a>() = 
    abstract member Generate: unit -> 'a 
    member this.Map (f:'a -> 'b) : Generator<'b> = 
     { new Generator<'b>() with 
      member __.Generate() = this.Generate() |> f 
     } 

注意到thisbase__的差異;)

BTW這甚至會沒有unit ->工作(因爲你寫的):Generate

[<AbstractClass>] 
type Generator<'a>() = 
    abstract member Generate: 'a 
    member this.Map (f:'a -> 'b) : Generator<'b> = 
     { new Generator<'b>() with 
      member __.Generate = this.Generate |> f 
     } 

當你變相的價值期待的方法,我不會推薦

更地道的方式

type Generator<'a> = unit -> 'a 

module Generator = 
    let map (f:'a -> 'b) (g : Generator<'a>) = 
     fun() -> g() |> f 

    let intGenerator : Generator<int> = 
     let rand = new System.Random() 
     fun() -> rand.Next(System.Int32.MinValue, System.Int32.MaxValue) 

有趣的事實

正如你可以在這裏看到(如果你仔細觀察),你會看到,這map其實只是函子 -Map爲unit -> *;)

免責聲明當然作爲發電機黯然不純沒有任何仿函數法真的會持有(如果你不修復你的系統時間)

+0

without'unit - >'Generate'將始終返回相同的生成值。編輯:對不起,我分心了,它實際上是一個屬性,用get方法;) –

+0

嘗試它;)...它在我的編譯器上工作:D(那些討厭的不純的獲得者) – Carsten

+0

謝謝卡斯滕。 –