【发布时间】:2013-09-15 21:24:39
【问题描述】:
背景
我正在使用 Scala 开发一个事件库。 In my library 你可以这样定义事件:
val e1 = new ImperativeEvent[Int]
你可以这样触发它们:
e1(42)
您可以像这样创建反应:
val r1 = (i: Int) => println(i)
并将它们附加到这样的事件中:
e1 += r1
还有一些其他的东西(比如事件转换、合成等)。我使用Esper CEP engine 作为我图书馆的后端。 Esper 对大多数操作使用一种称为 EPL 的类似 SQL 的语言。
问题
我正在尝试实现一些更高级的概念,例如事件连接。所以现在你可以像这样定义具有多个属性的事件(使用元组类型):
val e2 = new ImperativeEvent[(Int, String)]
然后像这样加入他们:
val e3 = e1 join e2 windowLength (30) on "E1.P1 = E2.P1"
在它们各自的第一个属性相等的条件下,对最后 30 次出现的 e1 和 e2 执行连接。
这没关系,但我想在我的实现中去掉字符串以使事件表达式类型可检查。我想把连接表达式改成这样:
val e3 = e1 join e2 windowLength (30) on e1._1 === e2._1
类似于它在例如完成的方式。 Squeryl。这样做的问题是,我无法访问元组类型的元素的类型...
问题
如何静态访问元组类型?现在我只能通过反射在运行时访问它们,这对我没有帮助。我很确定元组无法实现我想要实现的目标,但我想知道使用 shapeless 库中的 HLists 或类似的东西是否有助于实现我的目标。
【问题讨论】:
-
好像你有
e1.join(e2).windowLength(30).on(e1._1 === e2._1)。===是什么? -
+= 对于您在这里使用的操作符来说,这似乎是一个奇怪的选择。这意味着 ImperativeEvent 纯粹或主要是反应的集合。如果你重写了 + 来添加任何你可能添加到事件中的各种东西,我想这会更容易理解,但它仍然让我感到不安。
-
@pedrofurla E1 指连接的左侧事件,E2 指右侧连接事件。
join方法用适当的内部事件 ID 替换那些。实际的连接是由 Esper (esper.codehaus.org) 完成的,我的库主要是它的包装器。 Esper 基于一种称为 EPL 的类似 SQL 的语言,这就是它使用字符串的原因。我想为这些字符串添加类型检查(类似于例如 Squeryl,这就是我的===示例的来源)但我不确定这是否可以通过我当前的事件表示(其中参数表示为(元组)事件类型)。 -
@itsbruce
+=运算符的想法是从 C# 借来的。 Check this out 快速介绍 C# 事件。 -
所以有先例,我明白了,您正在为 C# 退伍军人提供熟悉的用法。不过,这是一个糟糕的先例;)如果它调用了一个名为
registerHandler之类的方法,那我每次都会使用它。