2016-07-25 14 views
0

Ich möchte eine Funktion erstellen, die einen Eingabetyp S übernimmt, wobei S <: ParentClass und S auch SomeTrait erbt. Ich habe eine Lösung mit S <: ParentClass with SomeTrait erstellt und kompiliert, aber es weist Eingaben zurück, die diese Bedingungen erfüllen.Scala-Funktion, die einen Typ erfordert, der sowohl eine Klasse als auch ein Merkmal erweitert

abstract class Units[T](v: T) { def getVal = v} 

trait Dimension 
trait Time extends Dimension 

trait Quantity[T <: Dimension] 
trait Instance[T <: Dimension] { 
    def plus[S <: Units[_] with Quantity[T]](q: S) 
} 

case class Seconds(v: Double) extends Units(v) with Quantity[Time] { 
} 
case class Timestamp(i: Int) extends Units(i) with Instance[Time] { 
    def plus[T <: Units[_] with Quantity[Time]](quantity: T) = Timestamp(2345/*placeholder value*/) 
} 

Wenn ich versuche, dies zu nutzen:

Timestamp(5).plus(Seconds(4)) 

ich den Fehler:

<console>:46: error: inferred type arguments [Seconds] do not conform to method plus's type parameter bounds [T <: Units[_] with Quantity[Time]] 
       Timestamp(5).plus(Seconds(4)) 
         ^
<console>:46: error: type mismatch; 
found : Seconds 
required: T 
       Timestamp(5).plus(Seconds(4)) 

Frage Bonus: Wie kann ich den Wert eines Artikels mit dieser Art erhalten, wie im Code angezeigt?

Antwort

1

Ihre Code-Typchecks für mich, sowohl in Scala 2.11.8 und in Scala 2.10.6.

> console 
[info] Starting scala interpreter... 
[info] 
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_31). 
Type in expressions for evaluation. Or try :help. 

scala> abstract class Units[T](v: T) { def getVal = v} 
defined class Units 

scala> 

scala> trait Dimension 
defined trait Dimension 

scala> trait Time extends Dimension 
defined trait Time 

scala> 

scala> trait Quantity[T <: Dimension] 
defined trait Quantity 

scala> trait Instance[T <: Dimension] { 
    | def plus[S <: Units[_] with Quantity[T]](q: S) 
    | } 
defined trait Instance 

scala> 

scala> case class Seconds(v: Double) extends Units(v) with Quantity[Time] { 
    | } 
defined class Seconds 

scala> case class Timestamp(i: Int) extends Units(i) with Instance[Time] { 
    | def plus[T <: Units[_] with Quantity[Time]](quantity: T) = Timestamp(2345/*placeholder value*/) 
    | } 
defined class Timestamp 

scala> Timestamp(5).plus(Seconds(4)) 

(A 2.10.6 REPL Konsole ist im Grunde identisch, also werde ich es überspringen.)

+0

Hm ich in Databricks testen, vielleicht einige seltsame Artefakt, dass ... Ich habe versucht, in der REPL und es tut typecheck, aber es gibt auch eine "Unit" von der "Plus" -Funktion zurück. – spiffman

+0

Nun, Ihre 'Plus'-Funktion gibt nicht an, was sie zurückgeben soll. Ich nehme an, dass scala davon ausgeht, dass Sie "Unit" meinen, wenn Sie den Rückgabetyp einer abstrakten Methode nicht angeben. –