我有一个问题在斯卡拉存在与工作。创建迷你工作流引擎时,我的问题就开始了。我开始的想法,这是一个有向图,实现对后者的第一个模型,然后仿照这样的工作流程:斯卡拉存在问题
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