在Interval
對象中使用Numeric
類型類的類型參數的類型參數爲T
,該類型參數必須在其封閉範圍內的某處進行綁定。作爲唯一常數值的Interval
不能提供該綁定。
一個解決這個特定的問題,將是您的union
和intersect
操作的定義移動到Interval
類作爲普通的實例方法,在這種情況下,他們將分享T
的結合,並與相關的Numeric
實例該類的其餘部分,
case class Interval[T : Numeric](from: T, to: T) {
import Numeric.Implicits._
import Ordering.Implicits._
def mid: Double = (from.toDouble + to.toDouble)/2.0
def union(interval2: Interval[T]) =
Interval(this.from min interval2.from, this.to max interval2.to)
def intersect(interval2: Interval[T]) =
Interval(this.from max interval2.from, this.to min interval2.to)
}
但是,如果您希望保留這些操作的定義,獨立於Interval
類,辦法來減少隱性的樣板,你需要追逐通過量量你的API是用Numeric [T]來定義你自己的更高級類型類。例如,
// Type class supplying union and intersection operations for values
// of type Interval[T]
class IntervalOps[T : Numeric] {
import Ordering.Implicits._
def union(interval1: Interval[T], interval2: Interval[T]) =
Interval[T](interval1.from min interval2.from, interval1.to max interval2.to)
def intersect(interval1: Interval[T], interval2: Interval[T]) =
Interval[T](interval1.from max interval2.from, interval1.to min interval2.to)
}
implicit def mkIntervalOps[T : Numeric] = new IntervalOps[T]
,在使用時會是什麼樣子,
def use[T](i1 : Interval[T], i2 : Interval[T])(implicit ops : IntervalOps[T]) = {
import ops._
val i3 = union(i1, i2)
val i4 = intersect(i1, i2)
(i3, i4)
}
第三個選項結合這兩點,使用隱含的定義,以豐富額外的方法原始類,
class IntervalOps[T : Numeric](interval1 : Interval[T]) {
import Ordering.Implicits._
def union(interval2: Interval[T]) =
Interval[T](interval1.from min interval2.from, interval1.to max interval2.to)
def intersect(interval2: Interval[T]) =
Interval[T](interval1.from max interval2.from, interval1.to min interval2.to)
}
implicit def enrichInterval[T : Numeric](interval1 : Interval[T]) =
new IntervalOps[T](interval1)
type Ops[T] = Interval[T] => IntervalOps[T]
然後在使用中,
def use[T](i1 : Interval[T], i2 : Interval[T])(implicit ops : Ops[T]) = {
val i3 = i1 union i2
val i4 = i1 intersect i2
(i3, i4)
}
謝謝。很簡潔。我從來沒有見過這種背景限制的想法。人們在哪裏學習這些東西?我讀過一本關於Scala的書,但我不記得上下文的界限。 –
請參閱示例[什麼是Scala中的「上下文綁定」?](http://stackoverflow.com/questions/2982276/what-is-a-context-bound-in-scala)。 – Jesper