Ошибка типа для ограничения контекста с неявными приоритетами

У меня есть следующая проблема, и я смущен тем, что происходит:

  1. У меня есть неявно определенный приоритет
  2. Я использую этот неявный приоритет, чтобы наложить привязку к контексту
  3. Я объявляю класс case с полем по умолчанию, значения которого покрываются привязкой к контексту.
  4. Я все еще получаю ошибку типа

Минимальный рабочий пример, отражающий фактический код, над которым я работаю. В основном мне нужен неявный приоритет в другой части моего кода:

    // 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)

Я получаю ошибку несоответствия типа:

required List[T0]

found List[Int]

Что здесь происходит? Я рассудил, что, поскольку я создаю свои параметры по умолчанию в границах, тип должен совпадать. Я пропустил какой-то трюк, чтобы заставить эту работу работать?


person finite_diffidence    schedule 15.07.2020    source источник
comment
Спасибо, мне нужно иметь какое-то значение по умолчанию, так как другие части кода используют конструктор по умолчанию. Я знаю, что могу удалить значение по умолчанию и заставить его работать, но для этого потребуется изменить очень большую базу кода. Есть ли способ заставить значение по умолчанию работать здесь или как-то предоставить доказательства?   -  person finite_diffidence    schedule 15.07.2020
comment
@finite_diffidence Ваш код не является MCRE, поскольку он компилирует scastie.scala-lang.org/W4jDvvnjSIu1JwSvw3yJrA Как воспроизвести ошибку компиляции?   -  person Dmytro Mitin    schedule 15.07.2020
comment
Извините, Дмитрий, кажется, моя IDE показывала ошибку на экране, я добавил строку в пример, но выдает другую ошибку о том, что имплициты не найдены - я думаю, что ошибка напрямую связана с невозможностью предоставить доказательства.   -  person finite_diffidence    schedule 16.07.2020
comment
@user Что, если кто-то ожидает, что местоположения будут List[String]? Это будет ошибка компиляции на сайте вызова, а не на сайте определения.   -  person Dmytro Mitin    schedule 16.07.2020
comment
@user Возможно, вы сможете использовать implicitly[List[T0]] и указать неявные значения List[Int] и т. д. Неявные значения стандартных типов, таких как List[...], действительно плохая идея.   -  person Dmytro Mitin    schedule 16.07.2020
comment
@DmytroMitin Я не имел в виду, что implicitly[List[T0]] было хорошим решением, просто вы могли использовать его в качестве пластыря. Однако я не знал, что вы можете предоставить такие аргументы по умолчанию. Я удалил свой комментарий сейчас.   -  person user    schedule 16.07.2020


Ответы (1)


Непонятно, как воспроизвести вашу ошибку компиляции

required List[T0]

found List[Int]

Код, который вы добавили

val t = Dog(age = 100)

выдает другую ошибку

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)

Это потому, что вы пропустили extends Stringifier[Int] и 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
person Dmytro Mitin    schedule 15.07.2020
comment
Спасибо @Dmytro, мне придется вернуться к моему коду и вернуться к нему - IDE по-прежнему показывает ошибку на моей стороне, когда я вношу ваши изменения, но код действительно компилируется. Я думаю, что это может быть что-то с моим IntelliJ, но я посмотрю. - person finite_diffidence; 16.07.2020
comment
@finite_diffidence На самом деле для меня IntelliJ 2020.1.3 тоже показывает несоответствие типов. Это ложное сообщение об ошибке компиляции. - person Dmytro Mitin; 16.07.2020