A Typescript library for working with immutable trees.
import {from, of, drawTree} from 'effect-tree'
console.log(
drawTree.doubleSpaceThin(
from('Hello', from('World', of('๐ณ')))
)
)
Prints:
โโฌHello
โ
โโโฌWorld
โ
โโโ๐ณ
You can find API documentation here.
Read here for more info on features, or just jump to the pretty pictures and proceed to running the examples.
pnpm install effect-tree
Everything can be imported from the top level entry-point effect-tree:
import {type Tree, from, append, of, drawTree, Codec} from 'effect-tree'
const myLeaf = of('๐')
console.log(drawTree.unlines(myLeaf))
// โ๐
const helloThere: Tree<string> = from('hello', of('there'))
const world: Tree<string> = append(helloThere, of('world'))
const encoded = Codec.Indented.encode(world)
console.log(encoded.join('\n'))
// hello
// there
// world
You can create leaves and branches with functions like of and from that return the type Tree, functions like branch and leaf that return Branch and Leaf, or use one of the many combinators available to build a tree in several steps.
You can unfold trees in various ways, decode trees from some encoded form, summon the nth tree from the enumeration of all ordered labeled trees, or generate random trees:
import {Arbitrary, type Tree, Codec, branch, leaf, nAryTree} from 'effect-tree'
import fc from 'fast-check'
// Manually
const myBranch = branch('1.', [leaf('2.1'), leaf('2.2')])
// Unfolding. Tree nodes will be set to node depth.
const myTernaryTree: Tree<number> = nAryTree({degree: 3, depth: 3})
// Decode from nested arrays.
const decodedTree: Tree<number> = Codec.Arrays.decode([1, [2, 3, [4, [5, 6]]]])
// Get the The 400,000,000,000,000th (4ร10ยนโด) labeled tree with 16 nodes:
const enumeratedTree = Codec.Prufer.getNthTree(4n * 10n ** 14n, 16)
// Generate a tree using โfast-checkโ
const randomTree = fc.sample(
Arbitrary.Tree.getArbitrary(fc.integer({min: 0, max: 10_000}), {
branchBias: 1 / 4,
maxDepth: 3,
maxChildren: 5,
}),
{numRuns: 1, seed: 42},
)
Draw themed trees to the terminal and compose custom layouts.
import {binaryTree, drawTree} from 'effect-tree'
import {pipe} from 'effect'
// A variant of โdrawTreeโ that renders
// numeric trees into a string
// โ
// โญโโโโโโโโโโโโดโโโโโโโโโโโโฎ
console.log(pipe(3, binaryTree, drawTree.number.unlines))
//โฌ1
//โโฌ2
//โโโ3
//โโโ3
//โโฌ2
// โโ3
// โโ3
For example with a zipper:
import {leaf, binaryTree, drawTree, Zipper} from 'effect-tree'
import {pipe} from 'effect'
console.log(
pipe(
3,
binaryTree,
Zipper.fromTree,
Zipper.head,
Zipper.head,
Zipper.replace(leaf(42)),
Zipper.toTree,
drawTree.unixRound.number.unlines,
),
)
// โ1
// โโ2
// โ โโ42 โ replaced
// โ โฐโ3
// โฐโ2
// โโ3
// โฐโ3