在函数参数中使用模式匹配
Use pattern matching in function parameters
我想知道是否可以指定作为参数传递给函数的节点的确切构造函数。例如,如果在 lang::java::m3::AST::Declaration
ADT 中,我将一个我知道必须是 \class()
的节点传递给一个函数,有没有办法指定它?
现在我有:
public void foo(lang::java::m3::AST::Declaration dec) { ... }
但我想要类似的东西:
public void foo(lang::java::m3::AST::\class(a,b,c,d) dec) { ... }
这样我就不必在 foo 内部进行匹配来到达 class 节点的部分。
或者,是否有其他更有效的方法。
谢谢!
当然可以,而且您可以将完整的模式匹配作为参数,而不必提及完整路径:
void foo(class(str a, str b, str c, list[Decl] d)) { ... }
或者也将 e
绑定到完整的 class 声明:
void foo(Decl e:class(str a, str b, str c, list[Decl] d)) { ... }
请注意,模式中的开放变量需要输入类型(与模式嵌套在函数体内时不同),这是因为我们不希望将类型错误传播到函数边界之外。
或者,您可能希望更深入地匹配并且 select 仅某些声明:
void foo(class("MyClass", str _, str _, list[Decl] _)) { ... }
或者,匹配所有 class 具有 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;
除了互斥之外,重载函数也需要完整。
这意味着对于您的 class 案例,您将需要为您不匹配的其他案例提供默认定义:
default void foo(Decl d) {
throw "did not implement foo for <d>";
}
可在此处找到更多信息:
我想知道是否可以指定作为参数传递给函数的节点的确切构造函数。例如,如果在 lang::java::m3::AST::Declaration
ADT 中,我将一个我知道必须是 \class()
的节点传递给一个函数,有没有办法指定它?
现在我有:
public void foo(lang::java::m3::AST::Declaration dec) { ... }
但我想要类似的东西:
public void foo(lang::java::m3::AST::\class(a,b,c,d) dec) { ... }
这样我就不必在 foo 内部进行匹配来到达 class 节点的部分。
或者,是否有其他更有效的方法。
谢谢!
当然可以,而且您可以将完整的模式匹配作为参数,而不必提及完整路径:
void foo(class(str a, str b, str c, list[Decl] d)) { ... }
或者也将 e
绑定到完整的 class 声明:
void foo(Decl e:class(str a, str b, str c, list[Decl] d)) { ... }
请注意,模式中的开放变量需要输入类型(与模式嵌套在函数体内时不同),这是因为我们不希望将类型错误传播到函数边界之外。
或者,您可能希望更深入地匹配并且 select 仅某些声明:
void foo(class("MyClass", str _, str _, list[Decl] _)) { ... }
或者,匹配所有 class 具有 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;
除了互斥之外,重载函数也需要完整。 这意味着对于您的 class 案例,您将需要为您不匹配的其他案例提供默认定义:
default void foo(Decl d) {
throw "did not implement foo for <d>";
}
可在此处找到更多信息: