4

关于版本:

"org.typelevel" %% "scodec-core" % "1.5.0"

我正在尝试使用 coproduct 功能,如测试用例中所示,演示将编解码器固定为已知子类型

我不断收到错误消息:“找不到参数 auto 的隐式值:scodec.codecs.CoproductBuilderAuto[my.class.here]”

我什至复制粘贴了这个例子,但无法让它工作:

import scalaz.\/
import shapeless._
import scodec.bits._
import scodec.codecs._
import scodec._

sealed trait Sprocket
object Sprocket {
  implicit val discriminated: Discriminated[Sprocket, Int] = Discriminated(uint8)
}

def codec(d: Int): Codec[Sprocket] = Codec.coproduct[Sprocket].discriminatedBy(provide(d)).auto

我将继续对此进行调查,但想知道最近是否有解决此问题的问题。我克隆了 repo,它可以从克隆中工作——但当我使用发布版本时却不行。

4

1 回答 1

5

示例代码中的错误是由于没有Sprocket定义任何子类型引起的。如果至少有 1 个子类型Sprocket,则 Shapeless 能够生成LabelledGeneric[Sprocket]表示为可区分联合的实例。联合是标记的子类型的副产品。

添加以下内容可解决错误:

case class Woozle(x: Int, y: Int) extends Sprocket
object Woozle {
  implicit val discriminator: Discriminator[Sprocket, Woozle, Int] = Discriminator(1)
  implicit val codec: Codec[Woozle] = (uint8 :: uint8).as[Woozle]
}

请注意,您需要同伴中的 thediscriminatorcodec隐含。如果discriminator未定义,您将收到报告的错误。如果codec未定义,您将得到一个发散的隐式错误。从理论上讲,Woozle如果存在隐式作用域,则编解码器可以自动派生Codec[Int],但 scalac 不能胜任这项任务——相反,它会因发散的隐式扩展错误而摆脱困境。我们希望通过 Shapeless 2.1 改进这一点。

供参考,完整来源:

import scalaz.\/
import shapeless._
import scodec.bits._
import scodec.codecs._
import scodec._

sealed trait Sprocket
object Sprocket {
  implicit val discriminated: Discriminated[Sprocket, Int] = Discriminated(uint8)
}

case class Woozle(x: Int, y: Int) extends Sprocket
object Woozle {
  implicit val discriminator: Discriminator[Sprocket, Woozle, Int] = Discriminator(1)
  implicit val codec: Codec[Woozle] = (uint8 :: uint8).as[Woozle]
}

object Main extends App {
  def codec(d: Int): Codec[Sprocket] = Codec.coproduct[Sprocket].discriminatedBy(provide(d)).auto
}

并构建:

scalaVersion := "2.11.4"

libraryDependencies += "org.typelevel" %% "scodec-core" % "1.5.0"
于 2014-11-15T04:14:52.373 回答