【问题标题】:Could not find implicit value for parameter lgen: shapeless.LabelledGeneric.Aux找不到参数 lgen 的隐式值:shapeless.LabelledGeneric.Aux
【发布时间】:2016-02-27 09:49:57
【问题描述】:

我是无形的新手。我有一个辅助类,它利用无形的“自动类型类派生”(https://gist.github.com/negator/fbbcd1b2ce9a85b762b7) 来帮助我填充 json 读取和写入。

import play.api.libs._
import json._

import shapeless.{ `::` => :#:, _ }
import poly._

object SReads extends LabelledTypeClassCompanion[Reads] {
  object typeClass extends LabelledTypeClass[Reads] {

    def emptyProduct: Reads[HNil] = Reads(_ => JsSuccess(HNil))

    def product[F, T <: HList](name: String, FHead: Reads[F], FTail: Reads[T]) = Reads[F :#: T] {
      case obj @ JsObject(fields) =>
      for {
        head <- FHead.reads(obj \ name)
        tail <- FTail.reads(obj - name)
        } yield head :: tail

        case _ => JsError("Json object required")
      }

    def project[F, G](instance: => Reads[G], to: F => G, from: G => F) = Reads[F](instance.map(from).reads)

    def emptyCoproduct: Reads[CNil] = Reads[CNil](_ => JsError("CNil object not available"))

    def coproduct[L, R <: Coproduct](
      name: String,
      cl: => Reads[L],
      cr: => Reads[R]) = Reads[L :+: R]{ js =>

      js match {
        case js @ JsString(n) if n == name => cl.reads(js).map(Inl.apply)
        case js @ _                        => cr.reads(js).map(Inr.apply)
      }
    }
  }
}

我是这样用的:

case class TrialMember(
  @Key("_id") var id: String,
  var weeks: String,
  var `type`: Option[String] = Some("email"),
  var updatedDate: Date = DateTime.now.toDate
)

object TrialMemberDao extends ModelCompanion[TrialMember, String] {
  def collection = mongoCollection("trial_member")
  val dao = new SalatDAO[TrialMember, String](collection) {}
  def emails() = dao.find(MongoDBObject("type" -> "email")).toList.map(_.id)
  def domains() = dao.find(MongoDBObject("type" -> "domain")).toList.map(_.id)
  def isTrialMember(userEmail: String): Boolean = {
    val trialMembers = emails() // whitelisted emails
    val trialDomains = domains() // whitelisted domains
    trialMembers.contains(userEmail) ||
      trialDomains.filter(userEmail.contains(_)).headOption.isDefined
  }

}

object TrialMember {
  implicit val jsonWrites: Writes[TrialMember] = SWrites.deriveInstance
  implicit val jsonReads: Reads[TrialMember] = SReads.deriveInstance
}

但是在升级到 sbt 0.13.8 和 Play 2.4 之后,现在它给了我这个错误:

could not find implicit value for parameter lgen: shapeless.LabelledGeneric.Aux[T,LKV]
[error]   implicit val reads: Reads[TrialMember] = SReads.deriveInstance

【问题讨论】:

  • 请提供您的Foo 定义。它看起来适合我的case class
  • @Odomontois 我编辑了这个问题。请看一看。

标签: scala sbt shapeless playframework-2.4


【解决方案1】:

问题有点好笑,您的类型类派生程序已完美实现,而编译器无法找到应用于 type 字段的 Option[String]Reads 实例。只需为您的代码提供类似以下定义的内容:

object optionFormats {
  def noneReads[T]: Reads[Option[T]] = Reads(Function.const(JsSuccess(None)))

  implicit def optFormat[T](implicit w: Writes[T], r: Reads[T]) =
    Format[Option[T]](
      r.map[Option[T]](Some(_)).orElse(noneReads),
      Writes(_.fold[JsValue](JsNull)(w.writes)))
}

然后在任何代码中

import optionFormats._

您的实例应该按照需要构建。

【讨论】:

  • 我应该在哪里提供这条线?我在对象 TrialMember 中使用它,它正在工作。但是我必须在所有对象类中都这样做。有没有办法修复 SReads?
  • @Odomontois 你知道为什么升级到 sbt 0.13.8 和 play 2.4 意味着旧代码不能再编译了吗?
猜你喜欢
  • 2017-02-02
  • 2016-01-17
  • 2011-10-17
  • 2016-03-31
  • 2015-01-27
  • 1970-01-01
  • 2016-02-22
  • 2011-04-15
  • 2015-06-28
相关资源
最近更新 更多