试图将F-bounded多态性建模为Scala中的类型成员

时间:2014-05-05 21:13:03

标签: scala polymorphism f-bounded-polymorphism

我想尝试编写一种类型,其方法可以是同类的,并返回相同类型的值:

object SimpleTest {
  trait Foo extends Product with Serializable {
    type Self <: Foo
    def bar: Self
  }

  case class X() extends Foo {
    type Self = X
    def bar = this
  }

  case class Y() extends Foo {
    type Self = Y
    def bar = this
  }


  trait TC[A]

  implicit val tc: TC[Foo] = new TC[Foo] { }

  def tester[A: TC](x: Seq[A]) = "foo"

  // tester(Seq(X(), Y()))
}

不幸的是,注释掉的行tester失败并出现以下错误(Scala 2.10):

Error: could not find implicit value for evidence parameter of type
SimpleTest.TC[SimpleTest.Foo{type Self >: SimpleTest.Y with SimpleTest.X <: SimpleTest.Foo}]
tester(Seq(X(), Y()))
      ^

基本上,我很困惑为什么XY没有统一到Foo,这对他们两个来说似乎是一个明确的LUB。很明显,类型成员使事情变得复杂,但其界限似乎得到了尊重。

在更高层次上,我正在寻找一种轻量级方法来获得相当于F-bounded多态性而无需普遍类型参数的开销。这似乎很有用,但我需要添加注释,强制XY统一到Foo

1 个答案:

答案 0 :(得分:17)

我认为这是您正在寻找的一个例子:

sealed trait Event { self =>
  type E >: self.type <: Event
  def instance: E = self
}

case class UserJoined() extends Event {
  type E = UserJoined
}

case class UserLeft() extends Event {
  type E = UserLeft
}

如果您想了解更多内容,此代码段来自a recent post,其中涵盖了相关概念。

编辑:要完成答案,它将是:

scala> trait Foo extends Product with Serializable with Event{}
defined trait Foo

scala> case class X() extends Foo {
     |     type Self = X
     |     def bar = this
     |   }
defined class X

scala> case class Y() extends Foo {
     |     type Self = Y
     |     def bar = this
     |   }
defined class Y

scala> List(X(),Y())
res9: List[Foo] = List(X(), Y())

scala>   def tester[A: TC](x: Seq[A]) = "foo"
tester: [A](x: Seq[A])(implicit evidence$1: TC[A])String

scala>  tester(Seq(X(), Y()))
res10: String = foo