4

这是一个非常精简的版本:

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

愚蠢的砖墙不让我通过。任何想法如何可能?秘密的斯卡拉隧道效应?希望...

4

3 回答 3

6

据我所知,Scala 编译器拒绝推断依赖于路径的类型,所以一点类型注释会有所帮助:

def test( m: Monoman ) { m.me( Brickwall[m.type]( m ).otherSide )}
于 2011-04-07T01:57:46.833 回答
3

是的,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) }

在您的情况下,这可能不是一个可行的解决方案。

于 2011-04-07T07:48:28.663 回答
1

这是工厂想法的尝试(我以前做过这个并放弃了,但是让我们再试一次):

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永远无法推断。

于 2011-04-07T14:51:51.010 回答