У меня есть следующий код в основном перебирать полей case class
и сопоставить их с помощью Poly
к тому же типу и использовать ToList[HL, Out]
Shapeless: Как выразить <: случай типа класса пары для Generix.Aux
для простоты мы можем предположить Poly
делает это:
object Schema extends Poly1 {
implicit def caseInt = at[Int](_ => "I'm an int")
implicit def caseString = at[String](_ => "Oh boy a string")
}
def infer[V1 <: Product, Out <: HList, MapperOut <: HList](v1: V1)(
implicit gen: Generic.Aux[V1, Out],
map: Mapper.Aux[Schema.type, Out, MapperOut],
to: ToList[MapperOut, String]
): List[String] = to (gen to v1 map Schema)
Это все очень просто и работает очень хорошо для простых сценариев:
case class Test(id: Int, text: String)
val list = infer(Test(2, "text"))
// List("I'm an int", "Oh boy a string")
Теперь выходить туда, где автобусы не работают:
class Automagical[T <: Product with Serializable : TypeTag] {
def instance: T
// The typetag bit is needed for something else
def convert: List[String] = infer(instance)
}
К сожалению, любой вызов выше терпит неудачу с:
could not find implicit value for parameter gen: shapeless.Generic.Aux[T,Out]
Bonus
Как я могу улучшить метод infer
не требуя экземпляра T
? Очевидно, что вывод типа прекрасен, но мне нужно как-то материализовать List[String]
с HList[Lub]
и переложить что-то на что-то.
Учитывая я только когда-либо заботиться о типах, можно вывести конкретный экземпляр List[String]
лишь зная типы быть поли отображенных кодируются как HList?
Что-то вроде:
def infer[V1 <: Product, Out <: HList, MapperOut <: HList]()(
implicit gen: Generic.Aux[V1, Out],
map: Mapper.Aux[Schema.type, Out, MapperOut],
to: ToList[MapperOut, String]
): List[String] = {
// Magically build an HList with samples from its types.
// Or an alternative approach that gives the same outcome
val reifiedInstance = reify[Out]
to (reifiedInstance map Schema)
}
Функция Automagical не компилируется для меня: «У черт нет параметров типа с границами контекста», но, конечно, указанная вами ошибка встречается и с абстрактным классом. – devkat
@devat Моя ошибка, это был класс в оригинальной реализации. – flavian