{"id":16618845,"url":"https://github.com/zwilias/elm-tree","last_synced_at":"2025-10-12T01:20:52.398Z","repository":{"id":62419691,"uuid":"80919144","full_name":"zwilias/elm-tree","owner":"zwilias","description":":deciduous_tree: Implementation of self-balancing trees in Elm","archived":false,"fork":false,"pushed_at":"2017-02-23T16:24:30.000Z","size":102,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-29T06:07:05.842Z","etag":null,"topics":["aa-tree","avl-tree","balanced-trees","self-balancing-trees","two-three-tree"],"latest_commit_sha":null,"homepage":"","language":"Elm","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zwilias.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-04T12:51:28.000Z","updated_at":"2022-12-06T20:19:21.000Z","dependencies_parsed_at":"2022-11-01T17:00:48.056Z","dependency_job_id":null,"html_url":"https://github.com/zwilias/elm-tree","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/zwilias/elm-tree","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zwilias%2Felm-tree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zwilias%2Felm-tree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zwilias%2Felm-tree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zwilias%2Felm-tree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zwilias","download_url":"https://codeload.github.com/zwilias/elm-tree/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zwilias%2Felm-tree/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279009736,"owners_count":26084645,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aa-tree","avl-tree","balanced-trees","self-balancing-trees","two-three-tree"],"created_at":"2024-10-12T02:21:48.060Z","updated_at":"2025-10-12T01:20:52.331Z","avatar_url":"https://github.com/zwilias.png","language":"Elm","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Self-balancing binary search trees, in Elm.\n\n[Self-balancing binary search trees](https://en.wikipedia.org/wiki/Self-balancing_binary_search_tree) are a node-based data structure that allow amortized worst case asymptotic `O (log n)` lookup, insertion and removal, as well as `O (n)` enumeration.\n\n## Basic tree operations\n\n\u003e Type signatures in this section assume a Tree type has been imported *and*\n\u003e exposed.\n\nThere are only a few operation that need to be implemented on a tree to allow\nthe construction of a more complete set of operations.\n\n### Construction\n\nFirst of all, we'll need some constructors.\n\n```elm\nTree.empty : Tree comparable\nTree.singleton : comparable -\u003e Tree comparable\n```\n\n`empty` allows creation of the empty, *null* tree. This is useful as a target\nfor folding or comparison to other nodes.\n\nUsing the `singleton` constructor, we can create a tree for one single *comparable* value.\n\n### Manipulation and inspection\n\nOther than construction, we'll also need some operations to manipulate and\ninspect the tree.\n\n```elm\nTree.insert : comparable -\u003e Tree comparable -\u003e Tree comparable\nTree.remove : comparable -\u003e Tree comparable -\u003e Tree comparable\nTree.member : comparable -\u003e Tree comparable -\u003e Bool\n```\n\n`insert` and `remove` speak for themselves: allowing the insertion into and\nremoval of nodes from a tree, means we can actually store the exact data we\nwant in a tree, and remove it once it is no longer required or once it needs to\nbe removed. Of course, without a way of knowing whether an element is in the\ntree, we can't do much with it. So, we also need a `member` function that will\ncheck if a given `comparable` appears in a given `Tree`.\n\n### Folding\n\n```elm\nTree.foldl : (comparable -\u003e a -\u003e a) -\u003e a -\u003e Tree comparable -\u003e a\nTree.foldr : (comparable -\u003e a -\u003e a) -\u003e a -\u003e Tree comparable -\u003e a\n```\n\nFinally, there is the pair of folding functions `foldl` and `foldr` that allow\nenumerating the values in a tree, passing them into an accumulator and finally,\nreturning this accumulated value. This accumulator could be any type of value,\nlike a single value (for example, to sum all the elements of a tree), a list or even a tree. Note that this enumeration happens in `O (n)`.\n\nUsing this last case -- folding a tree into another tree -- allows arbitrary\ntypes of manipulation. For example, removal of a node *could* be implemented as\nfolding all values *except the node to be removed* into a new tree. Of course,\nthat means the performance for removal would drop to `O (n)` rather than `O\n(log n)`, so that's not how it's implemented.\n\nHowever, a whole host of other operations could be defined -- in a rather\nperformant manner -- in terms of folding. `map`, `filter`, `toList`, `size`,\n`union`, `intersect`, `partition` and `difference` are a few standard\noperations that may be implemented this way, with example implementations given\nbelow.\n\n## Fold-based operations\n\nThis section is a quick overview of operations that can efficiently and often\nsuccinctly be implemented in terms of a fold.\n\n### toList\n\nConvert tree to list in ascending order, using `foldl`.\n\n*Example implementation:*\n\n```elm\ntoList : Tree comparable -\u003e List comparable\ntoList =\n    foldl (::) []\n```\n\n### fromList\n\nCreate tree from list by folding over the list and inserting into an initially empty tree. Folds over the list, rather than the tree.\n\n*Example implementation:*\n\n```elm\nfromList : List comparable -\u003e Tree comparable\nfromList =\n    List.foldl insert empty\n```\n\n### size\n\nFoldl over the list and incrementing an accumulator by one for each value that passes through the accumulator operation.\n\n*Example implementation:*\n\n```elm\nsize : Tree comparable -\u003e Int\nsize =\n    foldl (\\_ acc -\u003e acc + 1) 0\n```\n\n### map\n\nFold over the tree, executing the specified operation on each value, and\naccumulating these values into a new tree.\n\n*Example implementation:*\n\n```elm\nmap : (comparable -\u003e comparable2) -\u003e Tree comparable -\u003e Tree comparable2\nmap operator =\n    foldl\n        (insert \u003c\u003c operator)\n        empty\n```\n\n### filter\n\nCreate a new set with elements that match the predicate.\n\n*Example implementation:*\n\n```elm\nfilter : (comparable -\u003e Bool) -\u003e Tree comparable -\u003e Tree comparable\nfilter predicate =\n    foldl\n        (\\item -\u003e\n            if predicate item then\n                insert item\n            else\n                identity\n        )\n        empty\n```\n\n### union\n\nUnion is implemented by folding over the second tree and inserting it into the\nfirst tree.\n\n*Example implementation:*\n\n```elm\nunion : Tree comparable -\u003e Tree comparable -\u003e Tree comparable\nunion =\n    foldl insert\n```\n\n### intersect\n\nTree intersection creates a new Tree containing only those values found in both\ntrees. This is implemented by filtering the right-hand set, only keeping values\nfound in the left-hand set.\n\n*Example implementation:*\n\n```elm\nintersect : Tree comparable -\u003e Tree comparable -\u003e Tree comparable\nintersect left =\n    filter (flip member left)\n```\n\n### difference\n\nThe differences between two trees is, in Elm land, defined as the elements of\nthe left tree that do not exists in the right tree. As such, this is\nimplemented by filtering the left tree for values that do not exist in the\nright set.\n\n```elm\ndiff : Tree comparable -\u003e Tree comparable -\u003e Tree comparable\ndiff left right =\n    filter (not \u003c\u003c flip member right) left\n```\n\n### partition\n\nSimilar to filtering, this does not throw away the values that do not match the\npredicate, but creating a second tree from those values. The resulting trees\nare then returned as a tuple.\n\n*Example implementation:*\n\n```elm\npartition : (comparable -\u003e Bool) -\u003e Tree comparable -\u003e ( Tree comparable, Tree comparable )\npartition predicate =\n    foldl\n        (\\item -\u003e\n            if predicate item then\n                Tuple.mapFirst \u003c| insert item\n            else\n                Tuple.mapSecond \u003c| insert item\n        )\n        ( empty, empty )\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzwilias%2Felm-tree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzwilias%2Felm-tree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzwilias%2Felm-tree/lists"}