[英]Attempting to model F-bounded polymorphism as a type member in Scala
I wanted to try writing a type whose methods can be homogeneous and return values of the same type: 我想尝试编写一种类型,其方法可以是同质的,并返回相同类型的值:
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()))
}
Unfortunately, the commented-out line calling tester
fails with the following error (Scala 2.10): 不幸的是,注释掉的行调用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()))
^
Basically, I'm confused as to why X
and Y
don't unify to Foo
, which seems like a clear LUB for the two of them. 基本上,我对于X
和Y
为什么不统一为Foo
感到困惑,对于他们两个来说,LUB似乎是一个明确的LUB。 Clearly the type member is complicating matters but its bounds appear to be respected. 显然,类型成员使事务复杂化,但是似乎可以遵守其范围。
At the higher level, I'm looking for a lightweight way to get the equivalent of F-bounded polymorphism without the overhead of pervasive type parameters. 在更高的层次上,我正在寻找一种轻量级的方法来获得等效于F边界的多态性,而又不会增加泛型类型参数的开销。 This mostly seems to work, but I need to add annotations that force X
and Y
to unify to Foo
. 这似乎大部分都可行,但是我需要添加强制X
和Y
统一为Foo
注释。
I think this is an example of what you are looking for: 我认为这是您正在寻找的示例:
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
}
If you would like to read more, this snippet is from a recent post that covers related concepts. 如果您想了解更多信息,此摘录摘自涉及相关概念的最新文章 。
Edit: To complete the answer, it would be: 编辑:要完成答案,它将是:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.