Search code examples
scalacirce

Scala Circe - Extending Decoder getting no implicit arguments


I am still learning scala and attempting to use circe's decoders, but running into a little trouble with a context bound I think. I'm unsure why scala is expecting this implicit argument?

 abstract class Input[A](namedDecoder: String) extends Decoder[A]
  abstract class Test[T: Input](args: Int)

  case class InputImpl(hash: String, namedDecoder: String) extends Input(namedDecoder)
  class TestImpl(x: Int) extends Test[InputImpl](x)

I'm getting an error: No implicit arguments of type Input[InputImpl] and I'm a little confused what I'm missing here. Thanks for any help!


Solution

  • Actually, I think you don't want Input to be a Decoder but rather have an instance of Decoder associated with it.

    Check this code:

    abstract class Input[A](namedDecoder: String)
    final case class InputImpl(hash: String, namedDecoder: String) extends Input(namedDecoder)
    
    abstract class Test[T <: Input : Decoder](args: Int)
    class TestImpl(x: Int) extends Test[InputImpl](x)
    

    Otherwise, I really don't understand what is that you need to do, but maybe something like this?

    trait Input[A] {
      def decoder: Decoder[A]
      def namedDecoder: String
    }
    object Input {
      final class InputImpl[A](
          val hash: String,
          override final val namedDecoder: String,
          override final val decoder: Decoder[A]
      ) extends Input[A]
      
      implicit final def fromDecoder[A](implicit ev: Decoder[A]): Input[A] =
        new InputImpl(hash = "someHash", namedDecoder = "someName", decoder = ev)
    }
    
    abstract class Test[T: Input](args: Int)
    final class TestImpl(x: Int) extends Test[String](x)
    

    Although Input doesn't feel like a typeclass, why do you want to pass it implicitly? From where would things like hash and namedDecoder even come from? Those feel like just normal parameters.