Mys*_*Dan 13 polymorphism scala 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()))
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,注释掉的行调用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()))
^
Run Code Online (Sandbox Code Playgroud)
基本上,我很困惑为什么X和Y不统一Foo,这对他们两个来说似乎是一个明确的LUB.显然,类型成员使事情变得复杂,但其界限似乎得到尊重.
在更高的层次上,我正在寻找一种轻量级的方法来获得相当于F-bounded多态性而没有普遍类型参数的开销.这似乎很有效,但我需要添加强制X和Y统一的注释Foo.
leo*_*rim 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
}
Run Code Online (Sandbox Code Playgroud)
如果您想阅读更多内容,请参阅最近的一篇文章,内容涉及相关概念.
编辑:要完成答案,它将是:
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
Run Code Online (Sandbox Code Playgroud)