Вы не можете этого сделать. Обратите внимание, что
должен быть выведен во время выполнения
является противоречием. Вывод типа работает только во время компиляции.
Другими словами, когда вы пишете что-то вроде
val list: A :: B :: C :: C :: HNil = ...
тип переменной list
известен во время во время компиляции. Невозможно присвоить тип переменной во время выполнения, это просто не имеет смысла. Предположим, это было бы возможно, и у вас был бы волшебный метод toHlistMagical
:
val list: List[Parent] = A() :: B() :: C() :: C() :: Nil
val hlist = list.toHlistMagical // infers to A :: B :: C :: C :: HNil
Теперь давайте немного изменим его:
def getHlist(list: List[Parent]) = list.toHlistMagical
Какой тип возврата вы ожидаете от этой функции? Имейте в виду, что его можно вызывать с различными списками, а не только с теми, которые содержат экземпляры A
, B
, C
, C
в таком порядке:
getHlist(C() :: B() :: A() :: A() :: Nil)
Это может быть Any
, но тогда вы все равно можете просто использовать List
, потому что HList
больше нет, поэтому вы не получаете никакой дополнительной безопасности типов.
Вот почему toHlist
нужны типы:
def getHlist(list: List[Parent]) = list.toHlist[A :: B :: C :: C :: HNil]
getHlist
теперь имеет возвращаемый тип Option[A :: B :: C :: C :: HNil]
, потому что вы указали именно тот тип, который вам нужен, а toHlist
сможет выполнять проверку структуры list
во время выполнения и возвращать Some
, если список действительно содержит эти типы в этом порядке, или None
, если нет.
person
Vladimir Matveev
schedule
12.12.2014
List[Parent]
, вся информация о времени компиляции об отдельных элементах в списке (которая требуется для создания HList) исчезнет. Это необратимая операция. - person Jesper Nordenberg   schedule 12.12.2014