Ale*_*kov 5 wolfram-mathematica
我正在尝试使用可选参数定义替换规则color_RGBColor
,Sequence[]
当原始表达式中不存在时,该替换规则应替换为:
style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
Run Code Online (Sandbox Code Playgroud)
当RGBColor
原始表达式中存在时,规则有效:
style[Line[], RGBColor[{}]] /.
style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
=> {RGBColor[{}], Line[]}
Run Code Online (Sandbox Code Playgroud)
但是当它不存在时,它不会:
style[Line[], Thickness[0.01]] /.
Style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
=> style[Line[], Thickness[0.01]]
Run Code Online (Sandbox Code Playgroud)
我的问题是:
1)为什么它不起作用?
2)是否可以构建一个可以按要求工作的单一模式?
您的模式不起作用,因为模式匹配对默认(可选)参数起作用的方式,也因为您限制了头部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[]}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为匹配不正确 - 打字确实太弱了.使它工作的hacky方法是这样的:
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[]}
Run Code Online (Sandbox Code Playgroud)
建议的方法是:
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[]}
Run Code Online (Sandbox Code Playgroud)
模式匹配器的这个特性并不广为人知,因此我将再次强调它:(可选)模式的默认值x:ptrn:default
必须匹配ptrn
.有关此类行为的另一个示例,请参阅此 Mathgroup讨论.