我有一個問題在斯卡拉存在與工作。創建迷你工作流引擎時,我的問題就開始了。我開始的想法,這是一個有向圖,實現對後者的第一個模型,然後仿照這樣的工作流程:斯卡拉存在問題
case class Workflow private(states: List[StateDef], transitions: List[_, _], override val edges: Map[String, List[StateDef]]) extends Digraph[String, StateDef, Transition[_, _]](states, edges) { ... }
在這種情況下類,前兩個字段,它們的行爲狀態的列表作爲節點,表現爲邊緣的轉換。
的Transition
參數類型的輸入和輸出參數,因爲這應該表現爲在工作流程的可執行一塊,就像是某種功能:
case class Transition[-P, +R](tailState: StateDef, headState: StateDef, action: Action[P, R], condition: Option[Condition[P]] = None) extends Edge[String, StateDef](tailState, headState) {
def execute(param: P): Try[State[R]] = ...
}
我意識到很快,對付一個Workflow
對象中的轉換列表給我帶來了類型參數的麻煩。我試圖用[[Any]]和[[Nothing]]來使用參數,但我無法使其工作(gist [1])。
如果我要做Java,我會使用通配符?
並使用它的'less類型安全和更動態'屬性,Java必須相信我。但是Scala更加嚴格並且參數類型的變異和協方差很大,所以很難定義通配符並正確處理這些通配符。例如,使用forSome
符號和在Workflow
具有方法,我會得到這個誤差(要旨[2]):
Error:(55, 24) type mismatch;
found : List[A$A27.this.Transition[A$A27.this.CreateImage,A$A27.this.Image]]
required: List[A$A27.this.Transition[P forSome { type P },R forSome { type R }]]
lazy val w = Workflow(transitions)
^
因此然後我創建基於性狀的存在類型(要旨[3]), as explained in this article。
trait Transitions {
type Param
type Return
val transition: Transition[Param, Return]
val evidenceParam: StateValue[Param]
val evidenceReturn: StateValue[Return]
}
所以,現在我可以插入這個存在於我的Workflow
類是這樣的:
case class Workflow private(states: List[StateDef], transitions: List[Transitions], override val edges: Map[String, List[StateDef]])
extends Digraph[String, StateDef, Transitions](states, edges)
在一個小文件的工作被證明是工作(主旨[3])。但是當我轉移到真正的代碼時,我的Digraph
父類不喜歡這個存在的Transitions
。前者需要一個Edge[ID, V]
類型,其中Transition
符合但當然不存在Transitions
存在。
斯卡拉如何解決這種情況?使用參數類型來獲得Scala中的泛型似乎很麻煩。有沒有更容易的解決方案,我還沒有嘗試過?或者一個魔術技巧來指定Digraph
之間需要Edge[ID, V]
類型的正確兼容參數類型,而不是基本上擦除類型跟蹤的存在類型?
對不起,因爲這是令人費解的,我會盡我所能在必要時更新問題。
下面是我的一些試驗和錯誤的要義的引用:
- https://gist.github.com/jimleroyer/943efd00c764880b8119786d9dd6c3a2
- https://gist.github.com/jimleroyer/1ce238b3934882ddc02a09485f52f407
- EDIT-1基於@https://gist.github.com/jimleroyer/17227b7e334d020a21deb36086b9b978
HTNW答案,我修改使用forSome
的existentials的範圍和更新的解決方案:https://gist.github.com/jimleroyer/2cb4ccbec13620585d21d53b4431ce22
我還是雖然正確綁定與matchTransition
& getTransition
方法和不使用asInstanceOf
顯式轉換仿製藥的問題。我會開一個針對這個問題的另一個問題。
謝謝@HTNW,解決了一些我無法過去的編譯錯誤。這比我想象的更簡單。儘管我沒有將'matchTransition'和'getTransition'工作正常,但沒有強制轉換爲'instanceOf'。我用新版本創建了一個要點:https://gist.github.com/jimleroyer/2cb4ccbec13620585d21d53b4431ce22 你認爲有一種方法可以避免這種轉換嗎? 儘管如此,我覺得我應該接受你的答案,至少現在都在工作。我可以爲這個具體問題開一個新的問題。那會是SO標準嗎? – jlr
打開一個新問題,是的。 – HTNW