None Typeclass 的隐式查找与 Option 的 Contravariant Typeclass 不兼容
Implicit lookup for Typeclass of None is not compatible with Contravariant Typeclass of Option
我没有得到以下代码来编译,我很好奇我做错了什么。
我定义了一个 Contravariant Jsonwriter Trait 和一个接受隐式编写器的函数:
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])
请注意,第二个使用 type ascription 在 Nothing
(它是所有内容的子类型)
上放置一个面孔,可以这么说
None
,不说别的,就是一个Option[Nothing]
,所以OptionWriter[Nothing]
需要一个JsonWriter[Nothing]
。如果你试试 Json.toJson(Some(1))
是一样的,没有 JsonWriter[Int]
.
另一方面,Json.toJson(None:Option[String])
有效,因为 OptionWriter[String] 可以得到 JsonWriter[String]。
我没有得到以下代码来编译,我很好奇我做错了什么。
我定义了一个 Contravariant Jsonwriter Trait 和一个接受隐式编写器的函数:
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])
请注意,第二个使用 type ascription 在 Nothing
(它是所有内容的子类型)
None
,不说别的,就是一个Option[Nothing]
,所以OptionWriter[Nothing]
需要一个JsonWriter[Nothing]
。如果你试试 Json.toJson(Some(1))
是一样的,没有 JsonWriter[Int]
.
另一方面,Json.toJson(None:Option[String])
有效,因为 OptionWriter[String] 可以得到 JsonWriter[String]。