我是Scala的新手,也是更高级别的新手 . 我想写这样的东西;
trait Actor[E[Dependency] <: Event[Dependency]] {
def execute(dependency: Dependency): Unit
}
但是我不能在execute方法中引用类型参数Dependency - 编译器不知道它 .
我知道如果没有HKT,我可以通过以下方式解决它,但这不是这个问题的内容;
trait Actor[T <: Event[Dependency], Dependency] {
def execute(dependency: Dependency): Unit
}
我想理解为什么它不适用于我尝试过的更高级的kinded类型语法?是否有可能用HKT表达这一点?这是HKT的有效用例吗?
EDIT
更多信息,事件看起来像这样;
trait Event[Data] {
val payload: Data
}
......我正在寻找一个像这样的事件和演员;
case class FooEvent(payload: Foo) extends Event[Foo]
class FooActor extends Actor[FooEvent] {
def execute(dependency: Foo) = {}
}
2 回答
我会尽力改善阿列克谢的答案 - 他是对的,但他太矮了 . 但我必须说我不是HKT的专家,我想我才刚开始理解这个概念 .
在您的代码中
E[Dependency]
与E[_]
相同,后者表示您将某些类型作为参数E
. 这意味着您不能在Dependency
上操作类型 . 您也不能通过E
或E[Dependency]
作为类型操作 .E
是一个类型构造函数,如果我理解正确,E[Dependency]
是一个存在类型 . 请注意要么
也不会编译 .
您需要指定正确的类型作为执行的参数:
这个将编译为
E[B]
是此上下文中的类型 .Updated:
请看一下这段代码:
基本上诀窍是定义
type P
这是我们的Dependency
和type E = Event[P]
,它总是Event[Dependency]
然后您可以通过定义P
来使用actor,而不定义E
,因为它已经定义 . 不确定它是否解决了这个问题,但它看起来像是一种方式去找我 . 这里也有太多类型,有些像IntActor
则没有必要 . 我把它们放在一起,这样就更容易理解这个例子你不能,因为它不是
Actor
的参数 . 考虑更新:鉴于您的编辑,
[Dependency, T <: Event[Dependency]]
选项正是您所需要的 . 当你写Actor[E[Dependency] <: Event[Dependency]]
时,这意味着E
本身必须有一个类型参数 . 并且FooEvent
没有,所以Actor[FooEvent]
将无法编译 .更新2:您可以尝试使用类型成员,如下所示: