Tree/Rose.bruijn
# MIT License, Copyright (c) 2023 Marvin Borner
# Rose trees based on std/List
:import std/Combinator .
:import std/List L
:import std/Logic .
:import std/Math .
:import std/Pair .
# a tree node has a label as its head and subtrees as its tail
# constructs a tree with a label and no branches
leaf [0 : L.empty] ⧗ a → (RoseTree a)
{:}‣ leaf
# constructs a node with subnodes
node [[1 : 0]] ⧗ a → (List (RoseTree a)) → (RoseTree a)
{…:…} node
# returns the root label of a tree
label ^‣ ⧗ (RoseTree a) → a
^‣ label
# returns the branches of a tree
branches ~‣ ⧗ (RoseTree a) → (List (RoseTree a))
~‣ branches
# returns true if a tree is empty
empty? [L.empty? ~0] ⧗ (RoseTree a) → Boolean
∅?‣ empty?
:test (∅?({ 'a' : ({:}'b' : L.empty) })) (false)
:test (∅?({:}'a')) (true)
# applies a function to leaf and the leafs of all branches
map z [[[rec]]] ⧗ (a → b) → (RoseTree a) → (RoseTree b)
rec { (1 ^0) : (L.map (2 1) ~0) }
…<$>… map
:test (map ^‣ ({ "woo" : ({:}"oof" : (({ "aah" : ({:}"huh" : L.empty) }) : L.empty)) })) ({ 'w' : ({:}'o' : (({ 'a' : ({:}'h' : L.empty) }) : L.empty)) })
# maps a function returning list of trees and concatenates
concat-map L.concat ∘∘ map ⧗ ((RoseTree a) → (List (RoseTree b))) → (List (RoseTree a)) → (List (RoseTree b))
# folds a tree
# TODO: fix
fold [[[z [[rec]] 0]]] ⧗ (a → (List b) → b) → (RoseTree a) → b
rec ∅?0 case-end case-fold
case-fold 4 ^0 (1 ~0)
case-end 3
# :test (fold [[∅?0 (+1) (sum 0)]] ({ 'w' : ({:}'o' : (({ 'a' : ({:}'h' : L.empty) }) : L.empty)) })) ((+4))