流氓守卫

尼基塔·内姆金(Nikita Nemkin)

Rascal是否支持图案防护罩?

我正在尝试在构建中订购子表达式:

data Expr = and(Expr l, Expr r) | ... ;
Expr and(l, r) | r < l = and(r, l); // fictional syntax for "r < l" guard

如果没有警卫人员,那么实现上述目标的最佳方法是什么?

马克·希尔斯

只是为了简化事情我已经使用int作为类型l,并r在第一。您要执行的操作类似于以下内容:

rascal>data Expr = and(int l, int r);
ok

rascal>Expr and(int l, int r) = and(r,l) when r < l;
Expr (int, int): rascalfunction()

rascal>and(5,6);
Expr: and(5,6)

rascal>and(6,5);
Expr: and(5,6)

如果您创建的函数名称与返回要定义的数据类型的构造函数相同(例如Expr),则可以进行这种规范化。when子句说仅在条件匹配时才应用功能。您可能会遇到更复杂的条件,因此,如果您Expr将字段类型设置为字段,则可以使用类似的函数eval来实际计算表达式并返回结果。下面是一个部分示例(假设您只有一层嵌套):

rascal>data Expr = number(int n) | and(Expr l, Expr r);
ok

rascal>int eval(number(int n)) = n;
int (Expr): rascalfunction()

rascal>Expr and(Expr l, Expr r) = and(r,l) when eval(r) < eval(l);
Expr (Expr, Expr): rascalfunction()

rascal>and(number(5),number(6));
Expr: and(
  number(5),
  number(6))

rascal>and(number(6),number(5));
Expr: and(
  number(5),
  number(6))

要使用when,您需要使用此函数的表达式形式,在其中您要有一个=符号和返回值。如果规范化中的计算更加复杂,则可以执行以下操作:

Expr and(int l, int r) { 
    if (r < l) {
        return and(r,l); 
    } else {
        fail; 
    }
}

这本质上是做同样的事情。如果满足条件,and则返回的新版本如果不满足条件,fail则用于表示我们实际上并不希望应用此函数,因此将返回初始值:

rascal>and(5,6);
Expr: and(5,6)

rascal>and(6,5);
Expr: and(5,6)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章