[英]Scala higher kinded type syntax
我是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的有效用例嗎?
編輯
更多信息,事件看起來像這樣;
trait Event[Data] {
val payload: Data
}
......我正在尋找一個像這樣的事件和演員;
case class FooEvent(payload: Foo) extends Event[Foo]
class FooActor extends Actor[FooEvent] {
def execute(dependency: Foo) = {}
}
我會盡力改善阿列克謝的答案 - 他是對的,但他太矮了。 但我必須說我不是HKT的專家,我想我才剛開始理解這個概念。
在你的代碼中, E[Dependency]
與E[_]
相同,后者表示你有一些類型的E
作為參數。 這意味着您不會在Dependency
操作類型。 您也不能使用E
或E[Dependency]
作為類型。 E
是一個類型構造函數,如果我理解正確, E[Dependency]
是一個存在類型。 請注意
trait Actor[E[D] <: Event[D]] { def execute(d: E) {} }
要么
trait Actor[E[D] <: Event[D]] { def execute(d: E[D]) {} }
也不會編譯。
您需要指定正確的類型作為執行的參數:
trait Actor[E[D] <: Event[D]] { def execute[B](d: E[B]) {} }
這個將編譯為E[B]
是此上下文中的類型。
更新:
請看一下這段代碼:
trait Event[P] {
val payload: P
}
case class FooEvent(payload: Int) extends Event[Int]
trait BaseActor {
type E = Event[P]
type P
def execute(dep: P)
def runEvent(event: E)
}
trait IntActor extends BaseActor {
type P = Int
}
class FooActor extends IntActor {
def execute(dependency: P) = {}
def runEvent(event: E) = {}
}
val c = new FooActor()
c.runEvent(FooEvent(5))
c.execute(5)
基本上訣竅是定義type P
,它是我們的Dependency
, type E = Event[P]
,它總是Event[Dependency]
然后你可以通過定義P
而不定義E
來使用actor,因為它已經定義了。 不確定它是否解決了這個問題,但它看起來像是一種方式去找我。 這里也有太多類型,有些像IntActor
是不必要的。 我把它們放在一起,這樣就更容易理解這個例子
但是我不能在execute方法中引用類型參數Dependency - 編譯器不知道它。
你不能,因為它不是 Actor
的參數。 考慮
val actor = new Actor[Event] // E is Event
actor.execute(???) // what argument is this supposed to take? I.e. what is Dependency for Actor[Event]?
更新:鑒於您的編輯, [Dependency, T <: Event[Dependency]]
選項正是您所需要的。 當你編寫Actor[E[Dependency] <: Event[Dependency]]
,這意味着E
本身必須有一個類型參數。 並且FooEvent
沒有,所以Actor[FooEvent]
不會編譯。
更新2:您可以嘗試使用類型成員,如下所示:
trait Event {
type Dependency
val payload: Dependency
}
trait Actor {
type E <: Event
def execute(e: E#Dependency)
}
class Foo
case class FooEvent(payload: Foo) extends Event {
type Dependency = Foo
}
class FooActor extends Actor {
type E = FooEvent
def execute(e: Foo) = {}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.