在该操作中,我在RGL内部遇到了别名:
mkRoot3 : Str -> Root3 = fcl -> case fcl of {
f@? + c@? + l => {f = f ; c = c ; l = l} ;
_ => error ("mkRoot3: too short root" ++ fcl)
} ;
它是什么意思,有什么用?
字符@用于模式匹配。表达式foo@bar
表示您将某些内容与正则表达式bar
相匹配,并将结果绑定到变量foo
。
让我们首先回顾一下在没有@:的情况下对字符串进行模式匹配的一些方法
example1 : Str -> Str = s -> case s of {
"x" => "the string is exactly x" ;
"x" + _ => "the string starts with x" ;
? => "the string is one character long" ;
? + ? => "the string is two characters long" ;
("a"|"i"|"u") => "the string is a vowel" ;
_ => "whatever, I'm bored"
} ;
在所有这些操作中,我们没有重用右侧的字符串。如果你想这样做,你可以把它绑定到一个变量中,就像这样——还没有使用@,因为我们只是匹配一个字符串的开始和结束:
example2 : Str -> Str = s -> case s of {
"x" + rest => "the string starts with x and ends with" ++ rest ;
start + "x" => "the string starts with" ++ start ++ "and ends with x" ;
_ => "..." } ;
最后,如果您想将某个内容与正则表达式相匹配,并在RHS上使用与正则表达式匹配的内容,那么现在您需要使用@:
example3 : Str -> Str = s -> case s of {
v@("a"|"i"|"u") => "the string is the vowel" ++ v ;
a@? => "the string is one character long:" ++ a ;
a@? + b@? => "the string is two characters long:" ++ a ++ "followed by" ++ b ;
_ => "..." } ;
如果您只是尝试匹配a + b => …
或任何其他只包含变量的模式,它将无法匹配正好2个字符长的单词。相反,它只会将空字符串与其中一个匹配,将完整字符串与另一个匹配。
因此,匹配正则表达式?
(只匹配一个字符(,然后将结果绑定到变量,是唯一可以匹配具有精确长度的内容,然后重用右侧匹配的字符/字符串的方法。
有关模式匹配的更多信息,请访问http://www.grammaticalframework.org/doc/gf-refman.html#pattern-匹配。