我正在尝试使用可选参数color_RGBColor
定义替换规则,当原始表达式中不存在时,该替换规则应替换为Sequence[]
:
style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
当原始表达式中存在RGBColor
时,规则有效:
style[Line[], RGBColor[{}]] /.
style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
=> {RGBColor[{}], Line[]}
但是当它不存在时,它不会:
style[Line[], Thickness[0.01]] /.
Style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
=> style[Line[], Thickness[0.01]]
我的问题是:
1)为什么它不起作用?
2)是否有可能构建一个能够按预期工作的模式?
答案 0 :(得分:7)
您的模式不起作用,因为模式匹配对默认(可选)参数起作用的方式,也因为您将头部限制为RGBColor
。问题是默认参数值必须与模式匹配,而Unevaluated[Sequence[]]
肯定与_RGBColor
不匹配。
你有几种方法可以解决。第一次尝试是削弱你的类型检查:
In[10]:= style[Line[],Thickness[0.01]]/.
style[line_Line,___,color_: Unevaluated@Sequence[],___]:>{color,line}
Out[10]= {Thickness[0.01],Line[]}
但这不起作用,因为匹配不正确 - 输入确实太弱了。让它发挥作用的黑客方法是:
In[14]:= style[Line[], RGBColor[{}]] /.
style[line_Line, ___, color : (_RGBColor | _Unevaluated) :
Unevaluated@Sequence[], ___] :> {Evaluate@color, line}
Out[14]= {RGBColor[{}], Line[]}
In[15]:= style[Line[], Thickness[0.01]] /.
style[line_Line, ___, color : (_RGBColor | _Unevaluated) :
Unevaluated@Sequence[], ___] :> {Evaluate@color, line}
Out[15]= {Line[]}
建议的方法是:
In[18]:= style[Line[], Thickness[0.01]] /.
style[line_Line, ___, color : (_RGBColor | Automatic) : Automatic, ___] :>
If[color === Automatic, {line}, {color, line}]
Out[18]= {Line[]}
In[17]:= style[Line[], RGBColor[{}]] /.
style[line_Line, ___, color : (_RGBColor | Automatic) : Automatic, ___] :>
If[color === Automatic, {line}, {color, line}]
Out[17]= {RGBColor[{}], Line[]}
模式匹配器的这个特性并不广为人知,所以我将再次强调它:(可选)模式x:ptrn:default
的默认值必须与ptrn
匹配。有关此类行为的另一个示例,请参阅this Mathgroup讨论。
答案 1 :(得分:2)
也许这适合你:
style[Line[a], RGBColor[{}]] /.
style[line_Line, ___, Longest[color___RGBColor], ___] :> {color,line}
(*
{RGBColor[{}], Line[a]}
*)
style[Line[]] /.
style[line_Line, ___, Longest[color___RGBColor], ___] :> {color, line}
(*
{Line[]}
*)
我猜你的替换规则不起作用只是因为没有头部RGBColor
的元素,所以没有匹配。