Rascal 中的泛型类型 (&T)

Generic types (&T) in Rascal

我正在尝试使用 &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>");
            }
        }
    }
}

当我打印 e0e1e2 时:

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)

我真正想做的是能够遍历 e0e1 并提取这些列表中每个元素的类型。

我错过了什么/做错了什么?

谢谢!

流氓类型系统的原理是静态的。这可能令人困惑,因为我们还没有发布静态检查器,但是解释器目前模拟静态类型系统,因为我们一直在计划拥有一种静态类型的语言。

具体来说,这意味着您在函数体内使用的模式中使用的类型变量静态绑定到它们的上限,在您的例子中:值。这不是可枚举类型,这就是为什么 <- 的实现会报错。如果要匹配它需要更具体的类型,例如list[value]或list[&T],等价地。

顺便说一句,将类型参数绑定到更具体类型的方法是在函数头中使用它们。然后将使用实际参数的静态类型。另一种方法是在模式中使用带有可见声明的命名构造函数,这样参数位置可以分别与类型参数匹配。这不是很有用,因为如果您知道声明,则也不需要推断类型。

typeOf 函数 returns 值的动态类型,这解释了为什么您的打印件如所报告的那样工作。

这是否足够详细地回答了您的问题?