Packages

Data structures in pure Gleam! Including tree, heap, non empty list, map, set, and priority queue.

Current section

Files

Jump to
gleamy_structures src structures leftist_heap.gleam
Raw

src/structures/leftist_heap.gleam

// Based on "Purely Functional Data Structures" by Okasaki (1998)
import gleam/order.{Gt, Order}
type T(a) {
E
T(Int, a, T(a), T(a))
}
pub opaque type Heap(a) {
Heap(root: T(a), compare: fn(a, a) -> Order)
}
pub fn new(compare: fn(a, a) -> Order) -> Heap(a) {
Heap(E, compare)
}
pub fn insert(heap: Heap(a), item: a) -> Heap(a) {
Heap(merge(T(1, item, E, E), heap.root, heap.compare), heap.compare)
}
pub fn find_min(heap: Heap(a)) -> Result(a, Nil) {
case heap.root {
T(_, x, _, _) -> Ok(x)
E -> Error(Nil)
}
}
pub fn delete_min(heap: Heap(a)) -> Result(#(a, Heap(a)), Nil) {
case heap.root {
T(_, x, a, b) -> Ok(#(x, Heap(merge(a, b, heap.compare), heap.compare)))
E -> Error(Nil)
}
}
fn merge(h1: T(a), h2: T(a), compare: fn(a, a) -> Order) -> T(a) {
case h1, h2 {
h, E -> h
E, h -> h
T(_, x, a1, b1), T(_, y, a2, b2) ->
case compare(x, y) {
Gt -> make(y, a2, merge(h1, b2, compare))
_ -> make(x, a1, merge(b1, h2, compare))
}
}
}
fn make(x, a, b) {
let rank_a = case a {
T(r, _, _, _) -> r
E -> 0
}
let rank_b = case b {
T(r, _, _, _) -> r
E -> 0
}
case rank_a < rank_b {
True -> T(rank_a + 1, x, b, a)
_ -> T(rank_b + 1, x, a, b)
}
}