2014-03-12 240 views
0

這與this question有關,但我不明白在我的情況下如何使用存在類型會有所幫助。對象的斯卡拉類型參數

我試圖實現以下目標:

type MonadicArithmeticFunc[S] = (Int, S) => (Int, S) 

object addOne[S] extends MonadicArithmeticFunc[S] { 
    def apply(n: Int, s: S): (Int, S) = (n + 1, s) 
} 

val state = Seq.empty[Int] 
println(addOne(4, state)) 

但是作爲一個不能類型參數添加到一個對象,這並不工作。我試圖用一個存在的類型也:

object addOne extends MonadicArithmeticFunc[_] { 
    def apply[S](n: Int, s: S): (Int, S) = (n + 1, s) 
} 

但是,當然,這也不行,因爲適用的方法是不是發生在Function2類型參數。

我可以用一個基本的DEF:

def addOne[S](n: Int, s: S): (Int, S) = (n + 1, s) 

除非我必須聲明,在一個包對象,以獲得相同的作用域。任何其他想法?

+0

你想要達到的目標沒有意義,你的ArithmeticFunc在任何意義上都是非單調的,並且沒有理由將它用作超類,因爲你可以簡單地寫'object addOne {def apply [S](n: Int,s:S):(Int,S)=(n + 1,s)}'。你可以詳細說明你正在做什麼,它看起來像任何一種類型模式會讓你的生活變得更輕鬆或者斯卡拉狀態monad – 4lex1v

+0

只是好奇:你爲什麼要避免把東西放在包對象中? –

+0

我想問題是我想能夠使用'addOne'作爲函數對象,並且在'S'類型變化的各種情況下使用它。這樣可以,因爲addOne不關心S是什麼,它只是傳遞它。但是現在我意識到這在JVM中是不可能的。 –

回答

2

它根本沒有意義的,具有類型參數(或構造函數的參數,對於這個問題)爲object,因爲addOne[Int]addOne[String]會(大概)不同的對象,但關鍵字object意味着只應該是一個目的。你可以有

class addOne[S] extends MonadicArithmeticFunc[S] { 
    def apply(n: Int, s: S): (Int, S) = (n + 1, s) 
} 

object addOne { 
    def apply[S] = new addOne[S] 
} 

如果你真的需要MonadicArithmeticFunc出於某種原因。但正如Alexlv所說,

object addOne { 
    def apply[S](n: Int, s: S) = (n + 1, s) 
} 

通常會更可取。

+0

我喜歡class + object的例子。我會試試看。 –

+0

是的,我可以看到這是JVM的限制:每種類型都有不同的對象。因爲'addOne'不關心'S'的實際類型是什麼,所以我希望只有一個Function2的運行時對象 - 在運行時基本上是'Object',但沒有任何投射。我想我只需要爲每種類型分配'addOne'的單獨實例。 –