首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >None类型类的隐式查找与Option的Contravariant Typeclass不兼容

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

Stack Overflow用户
提问于 2018-08-09 14:29:26
回答 2查看 56关注 0票数 1

我不能编译下面的代码,我很好奇我做错了什么。

我定义了一个矛盾的Jsonwriter特征和一个接受隐式编写器的函数:

代码语言:javascript
复制
trait JsonWriter[-A] {
  def write(value: A): Json
}

object Json {
  def toJson[A](value: A)(implicit writer: JsonWriter[A]): Json =
  writer.write(value)
}

此外,我还定义了这些编写器的一些实例:

代码语言:javascript
复制
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)

}

现在我已经写了一个测试:

代码语言:javascript
复制
"write double Option" in {
  Some(1.0).toJson should be(JsNumber(1.0))
  None.toJson should be(JsNull)
}

第一个测试Some(1.0)运行良好,第二个测试None抛出:

代码语言:javascript
复制
Error:(40, 12) could not find implicit value for parameter writer: JsonWriter[None.type]
    None.toJson should be(JsNull)

如果您想尝试这些代码,我在此示例中的JsonType定义如下:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-09 15:31:51

如果你不说别的,None是一个Option[Nothing],所以OptionWriter[Nothing]需要一个JsonWriter[Nothing]。如果您尝试Json.toJson(Some(1))是相同的,则没有JsonWriter[Int]

另一方面,Json.toJson(None:Option[String])是有效的,因为OptionWriterString可以获得JsonWriterString。

票数 1
EN

Stack Overflow用户

发布于 2018-08-09 15:20:50

我认为这与以下事实有关

代码语言:javascript
复制
case object None extends Option[Nothing] { ... }

如果您执行以下操作之一,它将起作用

代码语言:javascript
复制
toJson(Option.empty[Double])
toJson(None : Option[Double])

请注意,第二个代码使用type ascriptionNothing (它是everything的一个子类型)上放置一个face

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51760206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档