[英]Implicit lookup for Typeclass of None is not compatible with Contravariant Typeclass of Option
我没有以下代码可以编译,而且我对自己做错了很好奇。
我定义了一个Contravariant Jsonwriter特性和一个接受隐式作者的函数:
trait JsonWriter[-A] {
def write(value: A): Json
}
object Json {
def toJson[A](value: A)(implicit writer: JsonWriter[A]): Json =
writer.write(value)
}
另外,我定义了这些作者的一些实例:
object JsonWriterInstances {
implicit val stringWriter: JsonWriter[String] =
(value: String) => JsString(value)
implicit val doubleWriter: JsonWriter[Double] =
(value: Double) => JsNumber(value)
class OptionWriter[-T](writer: JsonWriter[T]) extends JsonWriter[Option[T]] {
def write(value: Option[T]): Json = {
value match {
case None => JsNull
case Some(x) => writer.write(x)
}
}
}
implicit def optionWriter[T](implicit writer: JsonWriter[T]):
JsonWriter[Option[T]] = new OptionWriter[T](writer)
}
现在,我编写了一个测试:
"write double Option" in {
Some(1.0).toJson should be(JsNumber(1.0))
None.toJson should be(JsNull)
}
Some(1.0)的第一个测试工作正常,None的第二个测试抛出:
Error:(40, 12) could not find implicit value for parameter writer: JsonWriter[None.type]
None.toJson should be(JsNull)
如果您想尝试该代码,则本示例的JsonType定义为:
sealed trait Json
final case class JsObject(get: Map[String, Json]) extends Json
final case class JsString(get: String) extends Json
final case class JsNumber(get: Double) extends Json
case object JsNull extends Json
我认为这与以下事实有关
case object None extends Option[Nothing] { ... }
如果您执行以下任一操作,它将可以正常工作
toJson(Option.empty[Double])
toJson(None : Option[Double])
请注意,第二个使用类型归因将面孔(可以这么说)放在Nothing
(这是所有内容的子类型)
None
,如果您什么都不说,就是Option[Nothing]
,因此OptionWriter[Nothing]
需要一个JsonWriter[Nothing]
。 如果您尝试Json.toJson(Some(1))
相同,则没有JsonWriter[Int]
。
另一方面, Json.toJson(None:Option[String])
可以工作,因为OptionWriter [String]可以获取JsonWriter [String]。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.