2010-05-17 39 views
11

在「編程F#」我遇到這樣一個模式匹配來了(我簡化了一下):理解模式與利弊運營商匹配

let rec len list = 
    match list with 
    | [] -> 0 
    | [_] -> 1 
    | head :: tail -> 1 + len tail;; 

實際上,據我所知,在最後一次匹配識別頭名單的尾巴。從概念上講,我不明白它爲什麼起作用。據我所知,::是cons運算符,它在列表的頭部位置附加一個值,但它在我看來並不像它在這裏被用作操作符。我應該將它理解爲列表的「特殊語法」,其中::根據上下文將其解釋爲運算符或「匹配模式」?或者,對於其他運營商而言,是否可以將相同的想法擴展到列表以外的類型?

回答

10

除了Brian的回答,還有幾點值得注意。所述h::t語法可以既用作操作者爲圖案:

let l = 1::2::[]     // As an operator 
match l with x::xs -> 1 | [] -> 0 // As a pattern 

這意味着它是一個有點特殊構建體,因爲其它運營商(例如+)不能被用作圖案(用於分解結果返回到操作員的參數) - 顯然,對於+,這將是不明確的。

此外,模式[_]很有趣,因爲它是嵌套模式的一個例子。它組成:

  • _ - 下劃線圖案,它匹配的任何值,並且不結合任何符號
  • [ <pattern> ] - 單元素列表模式,它匹配單元素列表和列表的元素相匹配與嵌套<pattern>

你也可以寫match 1::[] with | [x] -> x這將返回單個元素的值(在本例中爲1)。

+0

謝謝,你關於::是一個特殊構造的觀點正是我不清楚的。我嘗試了使用其他運算符來匹配「相同」方式的模式匹配,但它沒有多少意義,我沒有任何地方,這讓我不知道有什麼缺點。 – Mathias 2010-05-17 17:55:58

+1

請注意,對於元組也是如此 - 您可以使用(,)模式構建和匹配/解壓縮元組,以及其他類型(Some()/ None)等等。 – Benjol 2010-05-18 08:34:26

+0

下面是[所有支持模式類型](https://docs.microsoft.com/zh-cn/dotnet/articles/fsharp/language-reference/pattern-matching)與示例。 – JanDotNet 2017-02-12 12:39:34

13

這是列表的特殊語法。你可以把list類型正是如此鑑別聯合:

type list<'T> =   // ' 
    | Nil 
    | Cons of 'T * list<'T> 

,除了有特殊的語法,使Nil[]Cons(h,t)h::t。然後這是一個歧視聯盟的正常模式匹配。這有幫助嗎?

(也可能見this blog entry。)

+0

這非常有幫助,謝謝! – Mathias 2010-05-17 05:30:41

2

它是用來作爲格式化器或正式pattern,`列表」被匹配到三個模式:

[]意味着該列表爲空

[_]表示列表有一個元素,因爲你不關心元素是什麼,所以簡單地把_放在那裏,你也可以使用[a]。

head :: tail表示列表確實有兩部分:頭部和尾部。

您可以將F#模式匹配視爲功能強大的if then else結構。