Chciałbym przekazać obiekt do funkcji, która akceptuje argument z rzutowanym typem, i uzyskać Scala, aby wydedukować, że typ obiektu pochodzi z obiektu, który go otacza. Oto niektóre prosty kod do zilustrowania trudności:Dlaczego Scala nie może wyprowadzić ścieżki typu zależnego od ścieżki, nawet z wyraźnego samoodniesienia?
trait Cult { cult_ =>
case class CultLeader(personality: Personality) {
val cult = cult_
val follower = personality.attractFollower(this)
}
case class Follower(leader: CultLeader, name: String)
}
trait Personality {
def attractFollower(leader: Cult#CultLeader) =
leader.cult.Follower(leader, "Fred") <-- THIS LINE FAILS TO COMPILE
}
Innymi słowy, osobowości CultLeader powinna przyciągnąć zwolennika do tego samego Cult jako CultLeader.
Scala 2.11.2 kompilator mówi:
TypeProjection.scala:11: error: type mismatch;
found : Cult#CultLeader
required: leader.cult.CultLeader
leader.cult.Follower(leader, "Fred")
^
To kompiluje i działa poprawnie, jeśli mogę dodać obsadę, tak:
leader.cult.Follower(leader.asInstanceOf[leader.cult.CultLeader], "Fred")
który wydaje niezdarny i wprowadza run-time sprawdzanie dla czegoś, co powinno być dedukowalne podczas kompilacji. Przynajmniej mam obejście. Jak mogę uzyskać kompilator Scala, aby wydedukować, że typ leader
jest w rzeczywistości leader.cult.CultLeader
?
Wolałbym nie przekazywać cult
jako kolejnego argumentu dla attractFollower
. W moim prawdziwym kodzie, mogłoby to spowodować wiele brzydkiego omijania parametru cult
- kiedy naprawdę nie powinno być w ogóle potrzebne.
Czy istnieje sposób na wymaganie, aby wyznawca pochodził z tego samego kultu, co "przywódca" wyznawcy? –
Tak, to było twoje oczywiste rozwiązanie - jednak nie możesz przekazać przywódcy ** jakiegokolwiek ** kultu dla naśladowcy, który wymaga przywódcy z ** betonu ** kultu - nie ma sposobu, aby to sprawdzić w czasie kompilacji Scala nie wie, jak dokładnie zostanie wywołany 'attractFollower' (może to być kod na zewnątrz modułu budowania). Zatem twoje rozwiązanie jest jak przekazanie 'Any', gdy funkcja wymaga' Int'. Nie ma więc potrzeby wymagać konkretnej projekcji kultowej i jednocześnie przekazywać projekcję - jest to logicznie niepoprawne. – dk14
Mimo że 'attractFollower' może być wywołany z dowolnego miejsca, czy nie powinien być w stanie stworzyć wyznawcy tego samego kultu, co lider, który został przekazany do' attractFollower'? –