Проезд одиночного типа через кирпичную стену - PullRequest
4 голосов
/ 07 апреля 2011

Вот очень сжатая версия:

case class Brickwall[A](otherSide: A)
trait Monoman { def me(m: this.type): Unit }

def test(m: Monoman): Unit = m.me(Brickwall(m).otherSide)

-> error: type mismatch;
 found   : Monoman
 required: m.type

тупая кирпичная стена не пропускает меня.есть идеи как это возможно?секретные эффекты туннеля скала?надеясь ...

Ответы [ 3 ]

6 голосов
/ 07 апреля 2011

Насколько я знаю, компилятор Scala отказывается выводить зависимые от пути типы, поэтому небольшая аннотация типов помогает:

def test( m: Monoman ) { m.me( Brickwall[m.type]( m ).otherSide )}
3 голосов
/ 07 апреля 2011

Да, синглтон-типы никогда не выводятся компилятором Scala.

Одна из возможностей - добавить фабричный метод к черте Monoman:

trait Monoman { 
  def me( m: this.type ) : Unit
  def createWall = Brickwall[this.type](this) 
}

def test( m: Monoman ) { m.me(m.createWall.otherSide) }

Возможно, это нереальное решение в вашем случае.

1 голос
/ 07 апреля 2011

Вот попытка с заводской идеей (я сделал это раньше и сдался, но давайте попробуем еще раз):

object Brickwall
case class Brickwall[A](brick: A)

trait Monoman { 
  var wall: Ref[this.type, Brickwall[String]]
  def ref[V](v: V): Ref[this.type, V]
}

object Ref {
  implicit def unwrap[Repr](r: Ref[_, Repr]): Repr = r.repr
  implicit def wrap[A, Repr](repr: Repr): Ref[A, Repr] = new Impl[A, Repr](repr)
  private class Impl[A, Repr](val repr: Repr) extends Ref[A, Repr]
}
trait Ref[A, Repr] { def repr: Repr }

def test(m: Monoman): Unit = {
  val w0 = m.wall
  val w1 = w0.copy(brick = "3.1415")
  m.wall = w1 // doesn't convert to Ref
}

так что, пока развертывание прозрачное, переупаковка, похоже, не работает, и я подозреваю, что заставить его работать не получится, опять же, потому что m.type никогда не может быть выведен.

...