Vorrei passare un oggetto a una funzione che accetta un argomento con un tipo proiettato, e ottenere Scala per dedurre che il tipo dell'oggetto proviene dall'oggetto che lo racchiude. Ecco alcune semplici righe di codice per illustrare la difficoltà:Perché Scala non può inferire il percorso di un tipo dipendente dal percorso, anche da un riferimento automatico esplicito?
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
}
In altre parole, la personalità di un CultLeader dovrebbe attrarre un seguace allo stesso culto come il CultLeader.
Il compilatore Scala 2.11.2 dice:
TypeProjection.scala:11: error: type mismatch;
found : Cult#CultLeader
required: leader.cult.CultLeader
leader.cult.Follower(leader, "Fred")
^
Si compila e funziona correttamente se aggiungo un cast, come questo:
leader.cult.Follower(leader.asInstanceOf[leader.cult.CultLeader], "Fred")
che sembra goffo e introduce run-time controllo per qualcosa che dovrebbe essere deducibile in fase di compilazione. Almeno ho una soluzione. Come posso ottenere che il compilatore Scala deduca che il tipo di leader
è infatti leader.cult.CultLeader
?
Preferirei non passare cult
come un altro argomento a attractFollower
. Nel mio codice attuale, ciò potrebbe comportare un brutto passaggio del parametro cult
, quando in realtà non dovrebbe essere affatto superato.
C'è un modo per richiedere che un follower provenga dallo stesso Culto del 'leader' del follower? –
Sì, quella era la tua soluzione precedente, ma non puoi passare un leader di ** qualsiasi ** cult ad un follower che richiede un leader di ** concreto ** cult - non c'è modo di controllarlo in fase di compilazione come Scala non sa come si chiamerà esattamente il tuo 'attractFollower' (potrebbe essere un codice al di fuori del modulo di costruzione). Quindi la tua soluzione è come passare 'Any' quando la funzione richiede 'Int'. Quindi non c'è modo di richiedere una proiezione di culto concreta e passare una proiezione simultaneamente - è logicamente scorretto. – dk14
Anche se 'attrFollower' può essere chiamato da qualsiasi luogo, non dovrebbe essere in grado di creare un Seguace dello stesso Culto del leader passato a 'attractFollower'? –