2014-10-19 3 views
2

У меня есть простую структуру дерева, как это ..печати элементов списка дерева кортеж в F #

type Tree<'a,'b> = 
    | Node of list<'a * Tree<'a,'b>> 
    | Leaf of 'b 

let phonebook = Node["MyPhonebook", 
        Node["Work", 
          Node["Company1", Node["Employee1", Leaf("phone#")]; 
           "Company2", Leaf("phone#")]; 
          "Private", 
          Node["Family", Node["Brother", Leaf("phone#");]; "Sister", Leaf("phone#")] 
         ] 
        ] 

Im просто пытается напечатать корневые папки (работы, Private) этой телефонной книги, но не могу показаться, чтобы получить это право все, что я делаю ...

let listelements tree = 
    match tree with 
    | Node[a, b] -> // OK - root node 
     printfn "%s" a // OK - root folder name 
     match b with 
     //| _ -> printf "%A" b // OK - prints whole node 
     | Node[a, b] -> printf "%A" a // Match failure! 

listelements phonebook 

После этого я понял, что я был соответствующий кортеж со списком, поэтому я пытался что-то немного другое, но я снова получить missmatches.

let phonebook = [Node["Work", 
         Node["Company1", Node["Employee1", Leaf("phone#")]; 
          "Company2", Leaf("phone#")]; 
         "Private", 
         Node["Family", Node["Brother", Leaf("phone#");]; "Sister", Leaf("phone#")] 
        ] 
       ] 

let listelements tree = 
    for i in tree do 
     match i with 
     | Node[a, b] -> printf "%s" a // Match fail 

let listelements tree = 
    //tree |> List.iter (fun x -> printf "%A" x) // OK - prints nodes 
    tree |> List.iter (fun x -> 
     match x with 
     | Node[a, b] -> printf "%A" a) // Match fail 

Что, черт возьми, я делаю неправильно здесь? Должен быть более элегантный и простой способ сделать это. Я пришел из C#, и это сводит меня с ума: P

ответ

1

Вы сопоставляете список одного элемента (кортежа) с List, поэтому в первом случае список содержит только один элемент и проходит через компилятор предупреждает, что совпадение является неполным. Но во втором матче список содержит два кортежа, поэтому он терпит неудачу.

Используйте вместо головы :: хвост шаблон, например:

| Node((a, b)::xs) 

или если вы не заинтересованы в хвосте у всех:

| Node((a, b)::_) 

NOTE

Something что поможет прояснить ваш код: tree - это список кортежей, как из определения. Это лучше, если вы пишете картину, делая круглые скобки кортежа явного, я имею в виду, если вы пишете:

| Node[(a, b)] -> 

вместо просто

| Node[a, b] -> 

Здесь компилятор понимает, что это кортеж, а человек не может, особенно если он исходит из фона Haskell.

Итак, запись скобок, вероятно, поможет вам понять, что проблема в том, что вы сопоставляете список с одним кортежем.

UPDATE

Если вы хотите напечатать все элементы, используя List.iter:

let rec listelements tree = 
    let printNode (a, b) = 
     printfn "%s" a 
     listelements b 
    match tree with 
    | Leaf leaf   -> printfn "Leaf %s" leaf 
    | Node(listOfNodes) -> List.iter printNode listOfNodes 
+0

я понял, что соответствие кортеж со списком, поэтому я удалить корневой кортеж и сделал все PHONEBOOK список, как писал в вопросе обновление. – mpkfa

+0

Я попытался с let listelements tree = tree |> List.iter (fun x -> match x with | Node ((a, b) :: _/xs) -> printf "% s" a), но только первый узел получает печататься? – mpkfa

+0

Нет, это не проблема. Вы не соответствовали кортежу против списка. Вы сопоставляли List (один) кортеж с списком (любого числа) кортежей. И проблема остается прежней, просто измените шаблон на тот, который я предлагаю, и он будет соответствовать. – Gustavo

Смежные вопросы