我有两种自定义数据类型
datatype expression = Constant of int
| Variable of string
| Operator of string * expression
| Pair of expression list
| List of expression list
datatype pattern = ConstantP of int
| VariableP of string
| OperatorP of string * pattern
| PairP of pattern list
| ListP of pattern list
| UnorderedListP of pattern list
| Wildcard
我应该实现一个功能
match (fn : expression * pattern -> (string * expression) list option)
获取表达式和模式。如果匹配,则返回SOME (list of bindings)
,否则返回NONE
。
匹配应该以这种方式进行:
匹配是在表达式的元组和列表(表达式*模式)上定义的。表达式和模式可以匹配与否。如果他们这样做,匹配产生一个绑定列表 - 名称和值对((字符串*表达式)列表),列表的顺序无关紧要。匹配使用以下规则:
如果你能给我一些方向的提示, 我认为我的功能应该是这样的,我猜,但不确定是否会以递归的方式覆盖所有情况
fun match(e: expression, p: pattern) : (string * expression) list option =
case p of
Wildcard => SOME []
| VariableP s => ...
答案 0 :(得分:2)
使用更多模式匹配。
然后逐个浏览规则列表并翻译它们,当规则依赖于子匹配时递归
您只需要定义匹配构造函数的情况,留下最后一个默认情况下的不匹配。
fun match (_, Wildcard) = SOME []
| match (Constant x, ConstantP y) = if x = y then SOME [] else NONE
| match (Pair [p1, p2], PairP [p1', p2']) =
let
val match1 = match (p1, p1')
in case match1 of
NONE => NONE
| SOME ls => ...
end
| ...
| match _ = NONE
但是你可以通过定义一些辅助函数来使事情变得更方便
(一旦你输入所有内容,上面的Pair
子句就会变得笨拙。)
例如,只有当两个可选列表都不是NONE
时才能将它们连接成一个函数非常简洁:
fun appendOptional (SOME xs, SOME ys) = SOME (xs @ ys)
| appendOptional _ = NONE
让你写一行
| match (Pair[p1, p2], PairP[p1', p2']) = appendOptional(match(p1, p1'), match(p2, p2'))
并且该功能在其他情况下也可以派上用场 (如果没有帮助函数,列表规则很难写,如果不是不可能的话。)
更详细的例子:
datatype expression = Constant of int
| Variable of string
| Pair of expression list
datatype pattern = ConstantP of int
| VariableP of string
| PairP of pattern list
| Wildcard
fun appendOptional (SOME xs, SOME ys) = SOME (xs @ ys)
| appendOptional _ = NONE
fun match (_, Wildcard) = SOME []
| match (Constant x, ConstantP y) = if x = y then SOME [] else NONE
| match (Pair [p1, p2], PairP [p1', p2']) = appendOptional (match (p1, p1'), match (p2, p2'))
| match (e, VariableP v) = SOME [(v, e)]
| match _ = NONE
测试:
- match (Constant 32, ConstantP 1);
val it = NONE : (string * expression) list option
- match (Constant 32, ConstantP 32);
val it = SOME [] : (string * expression) list option
- match (Constant 32, VariableP "x");
val it = SOME [("x",Constant 32)] : (string * expression) list option
- match (Pair [Constant 32, Variable "y"], PairP [VariableP "a", VariableP "b"]);
val it = SOME [("a",Constant 32),("b",Variable "y")]
: (string * expression) list option