У меня есть следующая реализация простого класса типов:
sealed trait Foo
object Foo {
case object A extends Foo
case object B extends Foo
}
sealed trait Baz
object Baz {
case object C extends Baz
case object D extends Baz
}
trait TC[C <: Foo, T <: Baz] {
val data: String
}
object instances {
implicit val a: TC[Foo.A.type, Baz.C.type] = new TC[Foo.A.type, Baz.C.type] {
val data = "some data"
}
implicit val b: TC[Foo.A.type, Baz.D.type] = new TC[Foo.A.type, Baz.D.type] {
val data = "some other data"
}
}
object syntax {
def getData[A <: Foo](b: Baz): String =
b match {
case Baz.C => implicitly[TC[A, Baz.C.type]].data
case Baz.D => implicitly[TC[A, Baz.D.type]].data
}
}
Я получаю следующую ошибку компиляции:
could not find implicit value for parameter e: TC[A,Baz.C.type]
case Baz.C => implicitly[TC[A, Baz.C.type]].data
Разве нельзя написать такую полиморфную функцию и разрешить экземпляр класса типов?
getData[Foo.B.type](Baz.C) = ???
,getData[Foo](Baz.C) = ???
,getData[Foo.A.type with Foo.B.type](Baz.C) = ???
,getData[Nothing](Baz.C) = ???
,getData[Null](Baz.C) = ???
,getData[Foo with Seq[Int]](Baz.C) = ???
. Итак, так многое может пойти не так.Идея typeclass состоит в том, чтобы избежать совпадений с этими шаблонами. Возможно, было бы полезно, если бы вы могли более подробно описать свою реальную проблему.
@LuisMiguelMejíaSuárez Я показал простой пример, так как думал, что это будет самый простой способ понять проблему. По сути, я хочу предоставить некоторый метод, который возвращает правильное значение в зависимости от типа Foo и типа Baz, который его вызывает.
так что в основном вы говорите, что механизм typeclass не должен использоваться с ADT
Проблема в том, что вы хотите, чтобы тип
B
был действительно известен во время выполнения, верно? - В любом случае, основная проблема сейчас заключается в том, что ваши экземпляры не входят в область действия и что компилятор не может знать, что будет экземпляр для любогоT <: Foo
.Да все верно