Last active
          May 1, 2025 11:20 
        
      - 
      
- 
        Save lamg/a10a289e597e6d667b3251ecff7b6d01 to your computer and use it in GitHub Desktop. 
Revisions
- 
        lamg revised this gist May 1, 2025 . 1 changed file with 2 additions and 4 deletions.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,6 @@ // the trick: // each node must be connected directly to its direct children (with visible characters) // and indirectly (through indentation) to its children's descendants type Tree<'a> = | Leaf of 'a 
- 
        lamg revised this gist May 1, 2025 . 1 changed file with 16 additions and 73 deletions.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,96 +1,39 @@ // the trick: // when you are in node N, with children XS // connect N directly to each X in XS // each X in XS produces a list of lines, // indent each one and include them in the result for N type Tree<'a> = | Leaf of 'a | Branch of 'a * list<Tree<'a>> let printTree (t: Tree<'a>) = let connectIndent (isLast: bool) (child: string, grandChild: string list) = let childConn, colConn = if isLast then "└── ", " " else "├── ", "│ " let connected = childConn + child let indented = grandChild |> List.map (fun x -> colConn + x) connected :: indented let rec treeToLines t = match t with | Branch(v, xs) -> let l = Seq.length xs let root = v.ToString() let children = xs |> List.mapi (fun i c -> treeToLines c |> connectIndent (i = l - 1)) |> List.concat root, children | Leaf v -> v.ToString(), [] let r, chl = treeToLines t r :: chl let tree = Branch(10, [ Branch(15, [ Leaf 12; Leaf 18 ]) ]) for x in printTree tree do printfn $"{x}" 
- 
        lamg revised this gist Jan 2, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -11,7 +11,7 @@ type PrinterContext<'a, 'b> = abstract member leafToString: 'b -> string // the trick: // when you are in node N, with children XS // connect N directly to each X in XS // each X in XS produces a list of lines, // indent each one and include them in the result for N 
- 
        lamg created this gist Aug 7, 2024 .There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,96 @@ type Branch<'a, 'b> = { value: 'a children: Tree<'a, 'b> seq } and Tree<'a, 'b> = | Branch of Branch<'a, 'b> | Leaf of 'b type PrinterContext<'a, 'b> = abstract member branchToString: 'a -> string abstract member leafToString: 'b -> string // the trick: // when you are in node N, wich children XS // connect N directly to each X in XS // each X in XS produces a list of lines, // indent each one and include them in the result for N let printTree (ctx: PrinterContext<'a, 'b>) (t: Tree<'a, 'b>) = let connectIndent (isLast: bool) (child: string, grandChild: string list) = let childConn, colConn = if isLast then "└── ", " " else "├── ", "│ " let connected = childConn + child let indented = grandChild |> List.map (fun x -> colConn + x) connected :: indented let rec treeToLines t = match t with | Branch { value = v; children = xs } -> let l = Seq.length xs let root = ctx.branchToString v let children = xs |> Seq.mapi (fun i c -> treeToLines c |> connectIndent (i = l - 1)) |> Seq.concat |> Seq.toList (root, children) | Leaf v -> ctx.leafToString v, [] let r, chl = treeToLines t r :: chl |> String.concat "\n" type Operator = | And | Or | Equivales type Identifier = string type Expression = Tree<Operator, Identifier> let binary op x y = Branch { value = op; children = [ x; y ] } let andOp x y : Expression = binary And x y let orOp x y : Expression = binary Or x y let equivOp x y : Expression = binary Equivales x y let x = Leaf "x" let y = Leaf "y" let z = Leaf "z" let original = "((x ≡ y) ∨ (y ≡ z)) ∧ z" let expr = andOp (orOp (equivOp x y) (equivOp y z)) z let ctx = { new PrinterContext<Operator, Identifier> with member _.branchToString op = match op with | And -> "∧" | Or -> "∨" | Equivales -> "≡" member _.leafToString l = l } printfn $"expression: {original}\n" printfn $"tree:\n{printTree ctx expr}" (* expression: ((x ≡ y) ∨ (y ≡ z)) ∧ z tree: ∧ ├── ∨ │ ├── ≡ │ │ ├── x │ │ └── y │ └── ≡ │ ├── y │ └── z └── z *)