【发布时间】:2021-01-09 15:23:30
【问题描述】:
我有一个经典的Encoder 类型类。
trait Encoder[A] {
def encode(a: A): String
}
我有两个问题
问题1:分歧从何而来:
[error] … diverging implicit expansion for type sbopt.Test.Encoder[None.type]
[error] starting with value stringEncoder in object Test
[error] show(None)
implicit val stringEncoder = new Encoder[String] {
override def encode(a: String): String = a
}
implicit def optionEncoder[A: Encoder]: Encoder[Option[A]] =
(a: Option[A]) => {
val encoderA = implicitly[Encoder[A]]
a.fold("")(encoderA.encode)
}
implicit def someEncoder[A: Encoder]: Encoder[Some[A]] =
(a: Some[A]) => {
val encoderA = implicitly[Encoder[A]]
encoderA.encode(a.get)
}
implicit def noneEncoder[A: Encoder]: Encoder[None.type] =
(_: None.type) => ""
def show[A: Encoder](a: A) = println(implicitly[Encoder[A]].encode(a))
show(None)
问题 2:我看到 Encoder 不是逆变的。有什么好处和坏处?
trait Encoder[-A] {
def encode(a: A): String
}
implicit val stringEncoder: Encoder[String] = (a: String) => a
implicit def optionEncoder[A: Encoder]: Encoder[Option[A]] =
(a: Option[A]) => {
val encoderA = implicitly[Encoder[A]]
a.fold("")(encoderA.encode)
}
def show[A: Encoder](a: A) = println(implicitly[Encoder[A]].encode(a))
show(Option("value"))
show(Some("value"))
show(None)
【问题讨论】:
-
不需要 None 和 Some 编码器。 Option 一个就足够了。
-
@LuisMiguelMejíaSuárez 这取决于您是否要显式指定
show的类型参数(或提供类型归属提示或使用智能构造函数.some、.none[A])以及多少类型-您将继续前进的水平。