Type Error for Context Bounding with Priority Implicits

56 views Asked by At

I have the following issue, and I am confused as to what is going:

  1. I have a priority implicit defined
  2. I use this priority implicit to impose a context bound
  3. I declare a case class with a default field, which has values that are covered by the context bound
  4. I am still getting a type error

A minimal working example which reflects the actual code I am working on. I basically need the priority implicits in other part of my code:

    // priority implicits
    sealed trait Stringifier[T] {
      def stringify(lst: List[T]): String
    }
    
    trait Int_Stringifier {
      implicit object IntStringifier {
        def stringify(lst: List[Int]): String = lst.toString()
      }
    }
    
    object Double_Stringifier extends Int_Stringifier {
      implicit object DoubleStringifier extends Stringifier[Double] {
        def stringify(lst: List[Double]): String = lst.toString()
      }
    }
    
    object Example extends App {
    
      trait Animal[T0] {
        def incrementAge(): Animal[T0]
      }
    
      case class Dog[T0: Stringifier]
      (age: Int = 0, locations: List[T0] = List(1, 2, 3)) extends Animal[String] {
        def incrementAge(): Dog[T0] = this.copy(age = age + 1)
      }
    }
 val t = Dog(age = 100)

I get a type mismatch error:

required List[T0]

found List[Int]

What is going on here? I reasoned that since I am creating my default parameters within the bound, the type should match. Am I missing some trick here to make this work?

1

There are 1 answers

2
Dmytro Mitin On BEST ANSWER

It's not clear how to reproduce your compile error

required List[T0]

found List[Int]

The code you added

val t = Dog(age = 100)

produces a different error

Error: could not find implicit value for evidence parameter of type App.Stringifier[Int]
Error occurred in an application involving default arguments.
    val t = Dog(age = 100)

This is because you missed extends Stringifier[Int] and import Double_Stringifier._

trait Int_Stringifier {
  implicit object IntStringifier extends Stringifier[Int] {
    def stringify(lst: List[Int]): String = lst.toString()
  }
}

import Double_Stringifier._

val t = Dog(age = 100) // compiles