Podczas uczenia się bezkształtnego zastanawiam się, dlaczego to się nie kompiluje:
def someHList[H <: HList]: H = HNil
skoro obiekt HNil rozszerza cechę HNil, która rozszerza listę HList?
Jaki jest właściwy sposób zdefiniowania metody w cechy, która zwraca pewną listę HList, która jest implementowana tylko przez rozszerzającą klasę?
Chciałbym zrobić coś takiego:
trait Parent {
def someHList[H <: HList]: H
}
object Child1 extends Parent {
def someHList[H <: HList] = HNil
}
object Child2 extends Parent {
def someHList[H <: HList] = 1 :: "two" :: HNil
}
Wszelkie porady są mile widziane. Dzięki!
EDYTOWAĆ
Aby rozwinąć, gdy zdam sobie sprawę z tego, co podkreśliłem w moim pierwotnym pytaniu:
1.) Pożądane jest, aby nie musieć określać H
wyraźnie w każdej klasie implementującej, ale pozwólcie, że można to wywnioskować (w witrynie wywoływania?).
2.) Chciałbym użyć HNil jako domyślnej implementacji cechy nadrzędnej, którą można opcjonalnie zastąpić w podklasach. Mój przykład prawdopodobnie powinien być:
trait Parent {
def someHList[H <: HList]: H = HNil
}
object Child extends Parent {
override def someHList[H <: HList] = 1 :: "two" :: HNill
}
Odpowiedzi:
8 dla odpowiedzi № 1HNil
obiekt jest HList
. Ale to nie jest konieczne H
.
definicja jak
def someHList[H <: HList]: H = HNil
należy czytać jako
dla każdego
type H
, podtypHList
istnieje sposób na zbudowanie jego członka i tak będzieHNil
co jest oczywiście błędne
To, co próbuję zrobić, jak czuję, to przeformułowana wersja tego
tam jest
type H
, podtypHList
i sposób na zbudowanie jego członka
Jeśli tak, możesz użyć takiego członka:
import shapeless._
trait Parent {
type H <: HList
def someHList: H
}
object Child1 extends Parent {
type H = HNil
def someHList: H = HNil
}
object Child2 extends Parent {
type H = Int :: String :: HNil
def someHList: H = 1 :: "two" :: HNil
}
Aktualizacja
Możesz także trochę go przeredagować, aby niektóre typy automatycznie wnioskowały
abstract class Parent[H <: HList](val someList: H)
object Child1 extends Parent(HNil: HNil)
object Child2 extends Parent(1 :: "two" :: HNil)
Możesz zauważyć, że ten typ dla HNil
jest ustawiany ręcznie, ponieważ typ object HNil
jest HNil.type
podtyp HNil
, który może czasami prowadzić kompilator w niewłaściwy sposób
4 dla odpowiedzi nr 2
Jeśli po prostu użyj HList
jako typ zwrotu wszystko działa dobrze:
trait Parent {
def someHList: HList
}
object Child1 extends Parent {
def someHList = HNil
}
object Child2 extends Parent {
def someHList = 1 :: "two" :: HNil
}
Lub w przypadku zaktualizowanej wersji pytania:
trait Parent {
def someHList: HList = HNil
}
object Child2 extends Parent {
override def someHList = 1 :: "two" :: HNil
}