Проблема в том, что вы слишком универсальны:
implicit def memberImplicit[A](
implicit // what you put here is irrelevant
): A = ...
При этом вы в основном предоставляете неявное значение для любого значения. Это противоречит любому другому определенному вами неявному параметру, а также любому неявному параметру, который вам нужно получить.
Но давайте спросим, почему компилятор не может доказать, что вы просто не можете предоставить имплициты, которые вы передаете в memberImplicit для плохих случаев, и поэтому он не будет считать это жизнеспособной альтернативой, и чтобы он мог доказать, что эта ветвь происхождения должна быть вырезать (там, где вы этого не намеревались), двусмысленность устранена, затем торт.
Дело в том, что вы возвращаете тип A. Это означает, что даже если вы добавили туда какое-то ограничение, например, A =:!= Params - в то время как обычно это работает ... вы просто предоставили все эти имплициты, поэтому ограничения типов перестали работать, и внезапно возникновение таких вещей, как, например, Selector[Params, String] имеют более одного способа создания экземпляров. В этой ситуации практически любая реализация, которую вы попробуете, - пока она возвращает A - потерпит неудачу.
Чтобы что-то работало, вы ДОЛЖНЫ ограничить вывод таким образом, чтобы он не совпадал со всем - на самом деле, чем меньше совпадений, тем лучше. Например, создайте отдельный тип-класс для извлечения значений из HLists:
trait Extractable[A] { def extract(): A }
object Extractable {
implicit def extractHList[H <: HList, A](
implicit
h: H,
selector: Selector[H, A]
): Extractable[A] = () => selector(h)
}
def extract[A](implicit extractable: Extractable[A]): A = extractable.extract()
а потом
extract[String] // "hello"
person
Mateusz Kubuszok
schedule
04.04.2020