[英]Type Class Implicits with Context Bound
I am slowly teaching myself Scala type classes.我正在慢慢地自学 Scala 类型的课程。 Suppose I have the following example:假设我有以下示例:
object Example extends App {
trait Serializer[T] {
def serialize(seq: Seq[T]): String
}
object Serializer {
def serialize[T](seq: Seq[T])(implicit serializer: Serializer[T]): Value = serializer.serialize(seq)
}
implicit object StringSerializer extends Serializer[String] {
def serialize(seq: Seq[String]): String = seq.toString()
}
implicit object IntSerializer extends Serializer[Int] {
def serialize(seq: Seq[Int]): String = seq.toString()
}
case class Data[T: Serializer](x: Seq[T], y: Seq[T], z: Seq[T]) {
val series = Data.createString(x, y, z)
}
object Data {
def createString[T : Serializer](x: Seq[T], y: Seq[T], z: Seq[T]) = {
val serialize = implicitly[Serializer[T]]
List(serialize.serialize(x), serialize.serialize(y))
}
}
val x = Seq("a", "b", "c")
val y = Seq(1, 2, 3, 4)
val z = Seq(10, 20, 30)
val data = Data(x, y, z)
println(data.series)
}
Now this fails with现在这失败了
could not find implicit value for evidence parameter of type Example.Serializer[Any] [error] val data = Data(x, y, z)找不到 Example.Serializer[Any] [error] val data = Data(x, y, z) 类型的证据参数的隐式值
Can someone please guide me as to how I can make createString
method work?有人可以指导我如何使createString
方法起作用吗? From my understanding because I have a Seq[Int]
and a Seq[String]
, the type [T]
will get inferred as [Any]
, which causes the issue.据我了解,因为我有一个Seq[Int]
和一个Seq[String]
,类型[T]
将被推断为[Any]
,这会导致问题。
However, I put a context bound based on my Serializer
type class, which I thought would make the compiler look for a String
or Int
serializer, which it fails to do.但是,我根据我的Serializer
器类型 class 放置了一个上下文绑定,我认为这会使编译器查找String
或Int
序列化器,但它无法做到这一点。 I basically want to pass in any sequence for which I have a defined serializer, so in this any combination of Seq[Int]
and Seq[String]
.我基本上想传递我定义了序列化程序的任何序列,所以在这个序列中Seq[Int]
和Seq[String]
的任意组合。
Any guidance would be much appreciated!任何指导将不胜感激!
Again the problem is that you want different types, but your are using a single type parameter T
;问题再次是您想要不同的类型,但您使用的是单个类型参数T
; so the compiler infers any.所以编译器推断出任何。
Maybe you want to define your class like this:也许您想像这样定义您的 class :
final case class Data[A: Serializer, B: Serializer, C: Serializer](x: Seq[A], y: Seq[B], z: Seq[C])
So you can have the three different types.所以你可以有三种不同的类型。
BTW, I would suggest you to use List or Vector or ArraySeq , ie concrete collections , instead of the abstract Seq .顺便说一句,我建议你使用List或Vector或ArraySeq ,即具体的 collections ,而不是抽象的Seq 。
If you want fields of Data
to be Seq
s of different element types then do this如果您希望Data
的字段是不同元素类型的Seq
,请执行此操作
case class Data[T: Serializer, T1: Serializer, T2: Serializer](x: Seq[T], y: Seq[T1], z: Seq[T2]) {
val series = Data.createString(x, y, z)
}
object Data {
def createString[T : Serializer, T1 : Serializer, T2 : Serializer](x: Seq[T], y: Seq[T1], z: Seq[T2]) = {
val serialize = implicitly[Serializer[T]]
val serialize1 = implicitly[Serializer[T1]]
val serialize2 = implicitly[Serializer[T2]]
List(serialize.serialize(x), serialize1.serialize(y), serialize2.serialize(z))
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.