无赖模式守卫
Rascal pattern guards
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)
如果您创建的函数与return您正在定义的数据类型的构造函数同名(例如,Expr
),这将允许您进行这种规范化. when
子句表示仅在条件匹配时应用该函数。你可能有一个更复杂的条件,所以如果你有 Expr
而不是作为字段的类型,你可以有一个像 eval
这样的函数,它实际上计算一个表达式并且 return 是一个结果。下面是一个部分示例(假设您只有一层嵌套):
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
,您需要使用函数的这种表达式形式,其中有一个=
符号和return 值。如果您在规范化中有更复杂的计算,您可以改为执行以下操作:
Expr and(int l, int r) {
if (r < l) {
return and(r,l);
} else {
fail;
}
}
这基本上做同样的事情。如果满足条件,and
的新版本将被 returned。如果不满足条件,用fail
表示我们实际上不想应用这个函数,所以初始值会是returned:
rascal>and(5,6);
Expr: and(5,6)
rascal>and(6,5);
Expr: and(5,6)
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)
如果您创建的函数与return您正在定义的数据类型的构造函数同名(例如,Expr
),这将允许您进行这种规范化. when
子句表示仅在条件匹配时应用该函数。你可能有一个更复杂的条件,所以如果你有 Expr
而不是作为字段的类型,你可以有一个像 eval
这样的函数,它实际上计算一个表达式并且 return 是一个结果。下面是一个部分示例(假设您只有一层嵌套):
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
,您需要使用函数的这种表达式形式,其中有一个=
符号和return 值。如果您在规范化中有更复杂的计算,您可以改为执行以下操作:
Expr and(int l, int r) {
if (r < l) {
return and(r,l);
} else {
fail;
}
}
这基本上做同样的事情。如果满足条件,and
的新版本将被 returned。如果不满足条件,用fail
表示我们实际上不想应用这个函数,所以初始值会是returned:
rascal>and(5,6);
Expr: and(5,6)
rascal>and(6,5);
Expr: and(5,6)