Я пытался сопоставить типы HList
с пакетом shapeless
от scala, не имея доступа к их значениям.Отобразить типы бесформенных HList
Следующая преуспевает в отображении значений из HList
import shapeless._
import shapeless.Poly._
import ops.hlist.Mapper
import ops.hlist.Mapper._
trait Person {
type Value
val v : Value
}
case class StringPerson extends Person {
type Value = String
val v = "I like strings"
}
case class IntPerson extends Person {
type Value = Int
val v = 42
}
object what_is_going_on {
object test_value_op {
val stringPerson = StringPerson()
val intPerson = IntPerson()
trait lpvfun extends Poly1 {
implicit def default[A <: Person] = at[A](_.v)
}
object vfun extends lpvfun {}
// Use these to generate compiler errors if the mapped type is not what we'd expect:
type TestListType = StringPerson :: IntPerson :: HNil
type TestListExpectedMappedType = String :: Int :: HNil
// Input:
val testList : TestListType = stringPerson :: intPerson :: HNil
// Output:
val mappedList : TestListExpectedMappedType = testList map vfun
// Get the actual mapped type
type TestListActualMappedType = mappedList.type
// This compiles......
val mappedList1 : TestListActualMappedType = mappedList
// .... but weirdly this line doesn't. That isn't the point of this question, but I'd be very grateful for an answer.
//implicitly[TestListActualMappedType =:= TestListExpectedMappedType]
}
}
Классный! Помимо того, что не удалось использовать implicitly[A =:= B]
, по какой-либо причине значения HList
были сопоставлены и имеют свои типы.
Теперь предположим, что у нас нет значения HList
, но мы знаем его тип. Как мы можем сопоставить его типы?
Я попытался следующие основанный на определении map
here:
object test_type_op {
type TestListType = StringPerson :: IntPerson :: HNil
type TestListExpectedMappedType = String :: Int :: HNil
// Attempt 1 does not work, compiler cannot prove =:=
type MappedType = Mapper[vfun.type, TestListType]#Out
implicitly[MappedType =:= TestListExpectedMappedType]
// Attempt 2 does not work, compiler cannot prove =:=
class GetMapper {
implicit val mapper : Mapper[vfun.type, TestListType]
implicitly[mapper.Out =:= TestListExpectedMappedType]
}
}
Как один получить тип отображенного HList
, не имея доступа к его стоимости? Есть ли способ отладки, почему компилятор не может что-то доказать? Спасибо за чтение.
Thankyou - это действительно помогает. Во втором блоке кода, что происходит с 'm' во время компиляции? Оптимизирован ли он? Есть ли способ получить тип, который 'm.Out' имел бы без фактического создания каких-либо значений? – user1158559