2012-09-12 67 views
0

我嘗試使用以下類型來表示在F#樹數據結構模式匹配我的樹內容:遍歷使用對象上

type Node = 
val mutable left: Node option 
val mutable right: Node option 
val mutable value: int 

new (l, r, v) = {left = l; right = r; value = v} 

我可以創建一個樹是這樣的:

let root = new Node (Some (new Node (None, None, 2)), Some (new Node (None, None, 3)), 1) 

我現在想要使用模式匹配來遍歷。但是,我不知道如何模式匹配對象。我試過這樣的事情:

let rec traverse r = 
    match r with 
    | Node (None, None, v) -> printfn "%d" v 

並停止在那裏,因爲模式匹配是錯誤的。

編輯: 經過Petricek的回答,我沒有使用他的所有建議,因爲我還沒有閱讀有歧視的工會和其他職業特點。一旦我對這些事情有更多瞭解,我會實施。但對於時間的存在,這是它的外觀:

type Node = 
val left: Node option 
val right: Node option 
val value: int 

new (l, r, v) = {left = l; right = r; value = v} 

let (|Node|) (nd: Node) = (nd.left, nd.right, nd.value) 

let root = new Node (Some (new Node (None, None, 2)), Some (new Node (None, None, 3)), 1) 

let rec traverseLRtR r = 
    match r with 
    | Node (None, None, v) -> printfn "%d" v 
    | Node (left, right, v) -> traverseLRtR left.Value; traverseLRtR right.Value; printfn "%d" v; 

traverseLRtR root 

輸出是:

2 
3 
1 

回答

3

Node類型需要讀取leftright領域提供會員。最地道的F#的方式來寫這樣的對象是使用:

type Node(left:Node option, right:Node option, value : int) = 
    member x.Left = left 
    member x.Right = right 

我刪除的字段的mutable屬性,因爲你不是在你的例如突變他們(但是你可以使用get & set性質,使他們可變的,如果這就是你想要的)。我還將代碼更改爲使用隱式構造函數語法,這更簡單。

作爲下一個步驟,可以編寫一個返回節點的部件的有源圖案:

let (|Node|) (nd:Node) = (nd.Left, nd.Right) 

然而,是否有爲什麼不使用F#識別聯合任何原因(即,C#兼容性)?這樣一來,你真的可以很容易地定義樹數據結構,你會得到的圖案爲無匹配:

type Node = Node of Node option * Node option * int 

然後你可以使用你寫的模式以創作上他們Node(None, Some ..., 42)和模式匹配構建節點。