当然可以,而且您可以将完整的模式匹配作为参数,而不必提及完整路径:
void foo(class(str a, str b, str c, list[Decl] d)) { ... }
或将e 绑定到完整的类声明:
void foo(Decl e:class(str a, str b, str c, list[Decl] d)) { ... }
请注意,模式中的开放变量需要类型化(与模式嵌套在函数体内时不同),这是因为我们不希望将类型错误传播到函数边界之外。
或者,您可能想要更深入地匹配并仅选择某些声明:
void foo(class("MyClass", str _, str _, list[Decl] _)) { ... }
或者,匹配所有具有 equals 方法的类的嵌套深度匹配:
void foo(class(str name, str _, str _, /method("equals",_,_)) { ... }
Rascal 函数定义的本质是它们可能被重载,并且调度是基于模式匹配动态完成的。作为程序员,您需要使模式互斥,或者如果这不可能,您可以使用default 修饰符来强制部分排序。
例如,这是非法的,因为模式0 与int n 重叠:
int f(0) = 1;
int f(int n) = f(n - 1) * n;
你可以这样写:
int f(0) = 1;
default f(int n) = f(n - 1) * n;
除了互斥之外,重载函数也需要完整。
这意味着对于您的类案例,您需要为其他不匹配的案例提供默认定义:
default void foo(Decl d) {
throw "did not implement foo for <d>";
}
更多信息可以在这里找到: