Шаблон (k1,k2)
должен быть перед неограниченным шаблоном k
, иначе все будет go до k
и ничего до (k1,k2)
.
Сопоставление с шаблоном в основном работает во время выполнения и вводит классы / имплициты в основном работают во время компиляции. Поскольку вы начали работать с классами типов (и, более того, с классами типов с типом-членом), похоже, что вы хотите иметь некоторые вычисления для типов, то есть некоторые вычисления во время компиляции.
Logi c ветвление во время выполнения соответствует для сопоставления с образцом. Логическое c ветвление во время компиляции соответствует классу типа и несколько последствий, определяющих экземпляры класса типа.
Попробуйте сделать a()
классом типа
trait A[K] {
def apply(key: K): Unit
}
object A {
implicit def tupleA[K](implicit identifiable: Identifiable.Aux[K, (String, String)]): A[K] = new A[K] {
override def apply(key: K): Unit = key match {
case (k1, k2) =>
val keyString: (String, String) = identifiable.identify(key)
()
}
}
implicit def defaultA[K](implicit identifiable: Identifiable.Aux[K, String]): A[K] = new A[K] {
override def apply(key: K): Unit = {
val keyString: String = identifiable.identify(key)
()
}
}
}
def a[K](key: K)(implicit aInstance: A[K]) = aInstance(key)
Вы должны написать несколько примеров того, как вы планируете применить свой a()
. На какие входы вы рассчитываете, какие выходы. Что должно компилироваться, что не должно компилироваться?
Обычно параметры типа (например, M
для Identifiable[M]
) похожи на входы, а члены типа (например, K
для Identifiable[M] { type K }
) похожи на выходные данные для типа- расчеты уровня. Поэтому для Identifiable
похоже, что тип K
будет выбран в зависимости от типа M
. Это правильно? Пожалуйста, подумайте о вашей логике c (что такое входы, какие выходы). В a()
вы, похоже, начинаете что-то делать, основываясь на типе K
.