我正在尝试使用&T
概念在Rascal中使用泛型类型。有些事我觉得有点奇怪。我不清楚为什么像下面这样的东西不起作用:
private tuple[str,int] synthesise_p(Fancy::AST::Exp exp, int count) {
switch (exp) {
case &T n(&T e0, &T e1, &T e2): {
println("e0: <e0> typeOf(e0): <typeOf(e0)>\ne1: <e1> typeOf(e1): <typeOf(e1)>\ne2: <e2> typeOf(e2): <typeOf(e2)>\n");
for (ty <- e0) {
println("ty: <ty>");
}
}
}
}
当我打印e0
,e1
和e2
时:
e0: ["x"] typeOf(e0): list(str()
e1: [nat(1),nat(2)] typeOf(e1): list(adt("Exp",[]))
e2: nat(3) typeOf(e2): adt("Exp",[])
出现以下错误:
|rascal://Synth::Synthesiser|(2291,2,<81,23>,<81,25>): value is not enumerable
?[Advice](http://tutor.rascal-mpl.org/Errors/Static/NotEnumerable/NotEnumerable.html)
我真正希望能够迭代e0
和e1
并提取这些列表中每个元素的类型。
我错过了什么/做错了什么?
谢谢!
答案 0 :(得分:1)
流氓式系统的原理是它是静态的。这可能会令人困惑,因为我们尚未发布静态检查器,但解释器当前模拟静态类型系统,因为我们一直在计划使用静态类型语言。
具体地说,这意味着在函数体内部使用的模式中使用的类型变量静态地绑定到它们的上限,在您的case:value中。这不是一个可枚举的类型,这就是为什么&lt; - 抱怨的实现。如果你想匹配它需要一个更具体的类型,如list [value]或list [&amp; T],等价。
顺便说一句,将类型参数绑定到更具体类型的方法是在函数头中使用它们。然后将使用实际参数的静态类型。另一种方法是在模式中使用带有可见声明的命名构造函数,以便参数位置可以分别与类型参数匹配。这不是很有用,因为如果您知道声明,则无需推断类型。
typeOf函数返回值的动态类型,这解释了为什么您的打印按照报告的方式工作。
这是否足够详细地回答了您的问题?