穿过砖墙驱动单例类型

发布于 2024-10-30 21:03:06 字数 298 浏览 0 评论 0原文

这是一个非常浓缩的版本:

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

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

Here is a very condensed version:

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

stupid brickwall doesn't let me through. any ideas how it might be possible? secret scala tunnel effects? hoping...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

幼儿园老大 2024-11-06 21:03:06

据我所知,Scala 编译器拒绝推断路径相关类型,因此一些类型注释会有所帮助:

def test( m: Monoman ) { m.me( Brickwall[m.type]( m ).otherSide )}

As far as I know the Scala compiler refuses to infer path dependent types, so a little type annotation helps:

def test( m: Monoman ) { m.me( Brickwall[m.type]( m ).otherSide )}
谈下烟灰 2024-11-06 21:03:06

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

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

Yes, singleton types are never inferred by the Scala compiler.

One possibility is to add a factory method to the Monoman trait:

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

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

Maybe that's not a viable solution in your case.

泪眸﹌ 2024-11-06 21:03:06

这是对工厂想法的尝试(我之前已经这样做过并放弃了,但是让我们再试一次):

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

here is a try with the factory idea (i had done this before and gave up, but well let's try again):

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
}

so while the unwrapping is transparent, the re-wrapping doesn't seem to be working, and i suspect it's not possible to get it working, again because m.type can never be inferred.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文