using LanguageExt; public struct Node where T : IComparable { public List> Children; public T Val { get; set; } public Node(T val) { Val = val; Children = new List>(); } public Node Insert(Node node) { if (!node.Val.Equals(Val)) Children.Add(node); return this; } public void Print() { Console.WriteLine($"[ {Val} ]"); if (Children.Count > 0) { Console.WriteLine($"Children of {Val} / total={Children.Count}:"); foreach (Node child in Children) child.Print(); } } } public static partial class Node { public static Node Traverse(this Node source, Func f) where T : IComparable where TResult : IComparable { Node result = new(f(source.Val)); foreach (Node child in source.Children) result.Children.Add(Traverse(child, f)); return result; } public static void ForAll (this Node source, Action f, AccT result) where SrcT : IComparable { f(source.Val, result); foreach (Node child in source.Children) ForAll(child, f, result); } } class Program { public static async Task> TryLoadCommentAsync(HttpClient client, int id) { try { return await client.GetStringAsync($"http://kit.local/comment/?id={id}"); } catch (HttpRequestException e) { return e; } } public static Either, Node>> TryLoadComments(Node tree) { using HttpClient client = new(); /* traverse tree */ var IdToResult = (int x) => { var task = TryLoadCommentAsync(client, x); return task.Result; }; var commentTree = Node.Traverse(tree, IdToResult); /* exceptions */ List errList = new(); var CollectExceptions = (Either val, List result) => { if (val.IsLeft) result.Add((Exception)val); /* really */ }; Node.ForAll(commentTree, CollectExceptions, errList); if (errList.Length() > 0) return errList; return commentTree; } public static void Main() { /* create tree */ Node a = new(100); Node b = new(101); Node c = new(102); Node bb = new(1000); b.Insert(bb); Node tree = new(10); tree.Insert(a).Insert(b).Insert(c); Node root = new(1); root.Insert(tree); Console.WriteLine("Source:"); root.Print(); var result = TryLoadComments(root); Console.WriteLine("Result:"); if (result.IsRight) ((Node>)result) /* really */ .Print(); else ((List)result) .ForEach((Exception e) => { Console.WriteLine(e.ToString()); }); } }