2012-03-12 4 views
2

型の不一致再帰的な処理リストとリストのサブリストは、私がリストやサブリスト レイアウトに分岐図を配置しよう

  • msg01
  • msg02
    • msg03
    • msg04
    • さを与えます
  • msg05

と私は分岐図の一番上を歩きたい - >下は各支店 に入るが、それは

エラータイプの不一致で失敗します。 ('a * 'b list) listを期待しかし「'a」と「'b * 'a list

を統合する際'b list与えられた結果の型は無限になることは誰もがこれを修正することができるもの私にいくつかのアイデアを与えることはできますか?さまざまな種類があり

open System 

let msgDiagram1 = [ ("msg03",[]); ("msg04",[]) ] 
let msgDiagram = [ ("msg01", []); ("msg02", msgDiagram1); ("msg05",[]) ]  

let listToString lst = 
    let rec loop acc = function 
     | [] -> acc 
     | x::xs -> let node = x 
        let sublst = snd(node)      
        if not (sublst = List.empty) then       
         loop "" sublst 
        else 
         loop (acc + (string x)) xs 

    loop "" lst 

printfn "%A" (listToString msgDiagram) 
+0

@padは以下のように、これをツリーとして構造化したいと思っています。 F#でツリーデータを構造化する方法と、それを操作する方法については、このブログのを参照してください。 –

答えて

4

msgDiagram1以来とmsgDiagram、あなたはそれらの上に同じloop機能を使用することはできません。一つの簡単な修正はmsgDiagram1で異なる処理することです:

let listToString lst = 
    let rec loop acc = function 
     | [] -> acc 
     | (lbl, diag)::xs -> 
      match diag with 
      | [] -> loop (acc + string lbl + "\n") xs 
      | _ -> 
       let s = diag |> List.map (fun (label, _) -> "..." + label) 
          |> String.concat "\n" 
       loop (acc + string lbl + "\n" + s + "\n") xs 
    loop "" lst 

あなたは仕事のための間違ったデータ構造を選択しました。したがって、2レベル以上の図を表現することはできず、これらのレベルは異なるタイプを持つことが強制されます。

let msgDiagram1 = [ Branch ("msg03",[]); Branch ("msg04", []) ] 
let msgDiagram = [ Branch ("msg01", []); Branch ("msg02", msgDiagram1); 
        Branch ("msg05", []) ] 

listToStringが一括して再帰的にDiagram listを処理するように書き換えることができる。

type Diagram = Branch of string * Diagram list 

次に上記の値は、同じタイプDiagram listを使用して定義することができる:ここで使用する適切なツールは、再帰的ツリーデータ構造であります。

関連する問題