How do you use Type Projections to p1 and p2 are the same type in p1.assign(p2)

喜你入骨 提交于 2019-12-13 08:31:47

问题


abstract class A {
  type ThisType <: A
  def assign(other: ThisType): ThisType
}

class B extends A {
  override type ThisType = B
  override def assign(other: B): B = ???
}

The possible places where p1 and p2 maybe declared. In essence they can be declared any where. I guess this would cover most of the usage scenarios:

1a)

implicit val p1: /* ??? */
implicit val p2: /* ??? */
implicit val f = { p1, p2 => p1.assign(p2) }
val c: => Unit = { p1, p2 => p1.assign(p2) }

object R1a {
  apply(implicit p1: B, p2: B, f: (B, B) => B) = new R1a(p1, p2, f)
}

val f: (B, B) => B = { p1, p2 => p1.assign(p2) }
class R1a(val p1: B, val p2: B, val f: (B, B) => B) extends Runnable {
  override def run: Unit = p1.assign(p2)
  // and val f: override def run: Unit = f(p1, p2)
}

1b)

implicit val p1: /* ??? */
implicit val p2: /* ??? */
implicit val f = { p1, p2 => p1.assign(p2) }
val c: => Unit = { p1, p2 => p1.assign(p2) }

object R1b {
  apply[T <: A](implicit p1: T, p2: T, f: (T, T) => T) = new R1a(p1, p2, f)
}

class R1b[T <: A](val p1: /* ??? */, val p2: /* ??? */, val f: (/* ??? */, /* ??? */T) => /* ??? */) extends Runnable {
  override def run: Unit = p1.assign(p2)
  // and val f: override def run: Unit = f(p1, p2)
}

2a)

class R2a extends Runnable {
  type T /* ??? */
  val p1: T = /* ??? */
  val p2: T = /* ??? */
  val f: (T, T) => T = { p1, p2 => p1.assign(p2) }
  override def run: Unit = p1.assign(p2)
  // and val f: override def run: Unit = f(p1, p2)
}

2b)

class R2b[T <: A] extends Runnable {
  val p1: /* ??? */
  val p2: /* ??? */
  val f: (T, T) => T = { p1, p2 => p1.assign(p2) }
  override def run: Unit = p1.assign(p2)
  // and val f: override def run: Unit = f(p1, p2)
}

3a)

class R3a extends Runnable {
  override def run: Unit = {
    type T /* ??? */
    val p1: T = /* ??? */
    val p2: T = /* ??? */
    val f: (T, T) => T = { p1, p2 => p1.assign(p2) }
    p1.assign(p2)
    // and f(p1, p2)
  }
}

3b)

class R3b[T <: A] extends Runnable {
  override def run: Unit = {
    val p1: /* ??? */ = /* ??? */
    val p2: /* ??? */ = /* ??? */
    val f: (T, T) => T = { p1, p2 => p1.assign(p2) }
    p1.assign(p2)
    // and f(p1, p2)
  }
}

/* ??? */ denotes a placeholder. No need to cover all the scenarios but as long as it is explained. I am trying to use this in a DSL hence there are times I am looking not to introduce new type parameters and also use them when they fit into the DSL design.

This is a follow up question to: How do I make sure a function receives the same parameter type as the current object?

If I have to do the assignment in function within a run function how do I achieve the same.

来源:https://stackoverflow.com/questions/39809778/how-do-you-use-type-projections-to-p1-and-p2-are-the-same-type-in-p1-assignp2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!