替换规则中带有可选参数的模式

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)是否可以构建一个可以按要求工作的单一模式?

Leo*_*rin 8

您的模式不起作用,因为模式匹配对默认(可选)参数起作用的方式,也因为您限制了头部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讨论.