Scodec - Coproducts could not find implicit value for parameter auto: scodec.codecs.CoproductBuilderAuto

604 Views Asked by At

On version:

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

I'm trying to use coproduct functionality, as shown in the test case demonstrate fixing the codec to a known subtype.

I keep getting the error: "could not find implicit value for parameter auto: scodec.codecs.CoproductBuilderAuto[my.class.here]"

I even copy pasted the example and could not get it to work:

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

I'll continue to look into this on my end, but was wondering if there was an issue fixed around this lately. I cloned the repo, and it worked from the clone - but not when I use the released version.

1

There are 1 best solutions below

2
On BEST ANSWER

The error from the example code is caused by not having any subtypes of Sprocket defined. If there's at least 1 subtype of Sprocket, then Shapeless is able to generate a LabelledGeneric[Sprocket] instance where the representation is a discriminated union. The union is a coproduct of labelled subtypes.

Adding the following resolves the error:

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]
}

Note that you need both the discriminator and the codec implicits in the companion. If the discriminator isn't defined, you'll get the reported error. If the codec isn't defined, you'll get a diverging implicit error. Theoretically, the Woozle codec could be automatically derived if there's an implicit Codec[Int] in scope, but scalac isn't up to the task -- instead, it bails out with a diverging implicit expansion error. We hope to improve this with Shapeless 2.1.

For reference, full source:

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
}

And build:

scalaVersion := "2.11.4"

libraryDependencies += "org.typelevel" %% "scodec-core" % "1.5.0"