Reputation: 639
I try to put a branching diagram into lists and sublists layout is
And i want to walk the branching diagram top -> bottom going into each branch but it fails with
Error Type mismatch. Expecting a
('a * 'b list) list
but given a'b list
The resulting type would be infinite when unifying ''a
' and ''b * 'a list
'
Can anybody gives me some ideas what could fix this?
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)
Upvotes: 2
Views: 261
Reputation: 41290
Since msgDiagram1
and msgDiagram
have different types, you cannot use the same loop
function on them. One quick fix is to process differently on 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
You chose a wrong data structure for the job; therefore, you cannot represent more than 2 levels of diagrams and these levels are forced to have different types. The right tool to use here is recursive tree data structure:
type Diagram = Branch of string * Diagram list
Now above values can be defined using the same type Diagram list
:
let msgDiagram1 = [ Branch ("msg03",[]); Branch ("msg04", []) ]
let msgDiagram = [ Branch ("msg01", []); Branch ("msg02", msgDiagram1);
Branch ("msg05", []) ]
and listToString
can be rewritten to process Diagram list
recursively in one batch.
Upvotes: 4