2011-06-19 22 views
5

我試圖定義一個可選參數color_RGBColor應與Sequence[]被替換替換規則時,它是在原有的表達缺失:模式與替換規則可選參數

style[line_Line, ___, 
    color_RGBColor: [email protected][], ___] :> {color, line} 

RGBColor出現在原始表達式,規則的工作原理:

style[Line[], RGBColor[{}]] /. 
style[line_Line, ___, 
    color_RGBColor: [email protected][], ___] :> {color, line} 

=> {RGBColor[{}], Line[]} 

但是,當它不存在,它不會:

style[Line[], Thickness[0.01]] /. 
Style[line_Line, ___, 
    color_RGBColor: [email protected][], ___] :> {color, line} 

=> style[Line[], Thickness[0.01]] 

我的問題是:

1)爲什麼它不起作用?

2)是否有可能構建一個可以按照需要工作的單一模式?

回答

7

由於模式匹配適用於默認(可選)參數,並且因爲您將頭限制爲RGBColor,所以您的模式不起作用。問題是默認參數值必須與模式匹配,而Unevaluated[Sequence[]]肯定不匹配_RGBColor

你有幾種出路。第一次嘗試是削弱你的類型檢查:

In[10]:= style[Line[],Thickness[0.01]]/. 
style[line_Line,___,color_: [email protected][],___]:>{color,line} 

Out[10]= {Thickness[0.01],Line[]} 

但是,這並不工作,因爲匹配是不正確的 - 打字確實太弱。使它工作的哈克的方式是這樣的:

In[14]:= style[Line[], RGBColor[{}]] /. 
style[line_Line, ___, color : (_RGBColor | _Unevaluated) : 
    [email protected][], ___] :> {[email protected], line} 


Out[14]= {RGBColor[{}], Line[]} 

In[15]:= style[Line[], Thickness[0.01]] /. 
    style[line_Line, ___, color : (_RGBColor | _Unevaluated) : 
    [email protected][], ___] :> {[email protected], 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討論。

+0

謝謝!這個功能完全沒有文檔嗎? –

+0

我還沒有看到它的記錄,但可能是我只是沒有足夠的重視,它寫在文檔中的某處。 –

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沒有元素用於更換的規則不只是工作,所以沒有比賽。

+0

以這種方式'最長'和甚至'可選'是不需要的 - 用'BlankNullSequence'代替'Blank'做竅門:'style [Line []] /。 style [line_Line,___,color___RGBColor,___]:> {color,line}'。但爲什麼它不適用於'空白'? –

+0

@Alexey我在編輯您的評論時:)。我也一樣 –