繁体   English   中英

None的隐式查找与Option的Contravariant Typeclass不兼容

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM