Я хотел бы передать объект функции, которая принимает аргумент с проецируемым типом, и заставить Scala вывести, что тип объекта поступает от объекта, который его охватывает. Вот некоторые простой код, чтобы проиллюстрировать сложность:Почему Scala не может определить путь зависимого от пути типа - даже из явной самореференции?
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
}
Другими словами, индивидуальность CultLeader должна привлечь последователя к тому же Cult как CultLeader.
Скала 2.11.2 компилятор говорит:
TypeProjection.scala:11: error: type mismatch;
found : Cult#CultLeader
required: leader.cult.CultLeader
leader.cult.Follower(leader, "Fred")
^
Он компилируется и работает правильно, если добавить оттенок, например:
leader.cult.Follower(leader.asInstanceOf[leader.cult.CultLeader], "Fred")
Это кажется неуклюжим и вводит проверку во время выполнения для чего-то, что должно быть выведено во время компиляции. По крайней мере, у меня есть обходной путь. Как я могу заставить компилятор Scala вывести, что тип leader
- это действительно leader.cult.CultLeader
?
Я бы предпочел не пропускать cult
как еще один аргумент attractFollower
. В моем действительном коде это может привести к множеству уродливых проходов вокруг параметра cult
- когда это действительно не нужно передавать вообще.
Есть ли способ требовать, чтобы последователь был от того же Культа, что и «лидер» последователя? –
Да, это было ваше безоговорочное решение - однако вы не можете передать лидеру ** любого ** культа последователю, который требует лидера от ** конкретного ** культа - нет способа проверить его во время компиляции, поскольку Scala не знает, как именно будет вызван ваш 'attractiveFollower' (это может быть код вне модуля сборки). Таким образом, ваше решение похоже на передачу 'Any', когда функция требует' Int'. Таким образом, не нужно требовать конкретной культовой проекции и пропускать любую проекцию одновременно - это логически неверно. – dk14
Даже если 'привлечьFollower' можно вызывать из любой точки мира, разве он не сможет создать последователя того же Культа, что и лидер, который был передан' attractiveFollower'? –