список рекурсивной обработки и подсписок списка дают несоответствие типов - PullRequest
2 голосов
/ 12 марта 2012

Я пытаюсь поместить диаграмму ветвления в списки и подсписки макет

  • msg01
  • msg02
    • msg03
    • msg04
  • msg05

И я хочу пройтись сверху вниз по ветвящейся диаграмме -> в каждой ветви но это не с

Ошибка несоответствия типов. Ожидается ('a * 'b list) list, но с учетом 'b list Результирующий тип будет бесконечным при объединении ''a' и ''b * 'a 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)

1 Ответ

4 голосов
/ 12 марта 2012

Поскольку 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

Вы выбрали неверную структуру данных для задания;следовательно, вы не можете представить более двух уровней диаграмм, и эти уровни вынуждены иметь разные типы.Правильный инструмент для использования здесь - это рекурсивная древовидная структура данных:

type Diagram = Branch of string * Diagram list

Теперь вышеуказанные значения могут быть определены с использованием того же типа Diagram list:

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

и listToString может бытьпереписан для обработки Diagram list рекурсивно в одной партии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...