Reputation: 159
I have following piece of code, and I think my question will be apparent once you see it.
trait hasId {
def id: String
}
trait hasCount {
def count: Int
}
case class Foo(id: String, count: Int) extends hasId with hasCount
// This is the function I want to write
def printData(data: hasId and hasCount): Unit = {
println(data.id + ": " data.count);
}
How should I do to declare the function signature?
Upvotes: 3
Views: 1525
Reputation: 4779
I somehow like @TerryDactyl's answer better, but here is another way:
// This is the corrected function
def printData(data: hasId with hasCount): Unit = {
println(data.id + ": " + data.count)
}
EDIT:
Since the comments showed that I needed to explain and since the scastie link didn't work, following is the compiled code, with the compilation errors, I hope it helps:
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait hasId {
def id: String
}
trait hasCount {
def count: Int
}
trait Both extends hasId with hasCount
case class Foo(id: String, count: Int) extends Both
case class Bar(id: String, count: Int) extends hasId with hasCount
case class Baz(id: String, count: Int) extends Both
def printData(data: hasId with hasCount): Unit = {
println(data.id + ": " + data.count)
}
def printDataT[T <: hasId with hasCount](data: T): Unit = {
println(data.id + ": " + data.count)
}
val s = Seq(Foo("idFoo", 1), Bar("idBar", 2))
val fooss = Seq(Foo("idFoo", 1), Foo("idFoo2", 2))
val boths = Seq(Foo("idFoo", 1), Baz("idBaz2", 2))
s.foreach(printData)
fooss.foreach(printData)
boths.foreach(printData)
fooss.foreach(printDataT[Foo])
fooss.foreach(printDataT[Both])
boths.foreach(printDataT[Both])
boths.foreach(printDataT[Foo])
s.foreach(printDataT[hasId with hasCount])
s.foreach(printDataT[Both])
s.foreach(printDataT[Foo])
// Exiting paste mode, now interpreting.
<console>:54: error: type mismatch;
found : Foo => Unit
required: Product with Serializable with hasId with hasCount => ?
s.foreach(printDataT[Foo])
^
<console>:48: error: type mismatch;
found : Foo => Unit
required: Both with Product with Serializable => ?
boths.foreach(printDataT[Foo])
^
<console>:51: error: type mismatch;
found : Both => Unit
required: Product with Serializable with hasId with hasCount => ?
s.foreach(printDataT[Both])
^
Upvotes: 0
Reputation: 34453
The solution to the answer is with
keyword, which is used in the meaning of your and
. Generics as Terry Dactyl wrote are one possible solution:
def printData[T <: hasId with hasCount](data: T): Unit = {
println(data.id + ": " + data.count)
}
Another is a type
alias using with
:
type hasIdAndCount = hasId with hasCount
def printData(data: hasIdAndCount): Unit = {
println(data.id + ": " + data.count)
}
Or even directly:
def printData(data: hasId with hasCount): Unit = {
println(data.id + ": " + data.count)
}
Upvotes: 6