尝试将F界多态性建模为Scala中的类型成员 [英] 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()))
}
不幸的是,调用tester
的注释行失败并出现以下错误(Scala 2.10):
Unfortunately, the commented-out line calling tester
fails with the following error (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()))
^
基本上,我对为什么X
和Y
不统一为Foo
感到困惑,对于这两个人来说,这似乎是一个明确的LUB.显然,类型成员正在使事情复杂化,但是其边界似乎受到了尊重.
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. Clearly the type member is complicating matters but its bounds appear to be respected.
在更高的层次上,我正在寻找一种轻量级的方法来获得与F界多态等效的方法,而又不会增加泛型类型参数的开销.这似乎大部分都可行,但是我需要添加强制X
和Y
统一为Foo
的注释.
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. This mostly seems to work, but I need to add annotations that force X
and Y
to unify to 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.
要完成答案,应为:
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
这篇关于尝试将F界多态性建模为Scala中的类型成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!