# Stack — foundational LIFO stack for Bend. # Publish entry for this package. Depends only on Base (does not reimplement List). # # Encoding: a thin wrapper over List with the top at the list head. # to_list is top-first (list head = stack top), not bottom-first. # Quantity: Stack is Kind(a), same convention as List/Maybe. import Base type Stack is Kind(a): S{data: List} # Pop view: head + remaining stack. type Stack.Pop is Kind(a): HD{head: A, rest: Stack} def Stack.empty(a, -A: Kind(a)) -> Stack: S{Nil{}} def Stack.push(a, -A: Kind(a), s: Stack, x: A) -> Stack: match s: case S{xs}: S{x <> xs} def Stack.pop.go(a, -A: Kind(a), s: Stack) -> Maybe>: match s: case S{xs}: match xs: case Nil{}: None{} case h <> t: Some{HD{h, S{t}}} def Stack.pop(a, -A: Kind(a), s: Stack) -> Maybe>: Stack.pop.go(a, A, s) def Stack.peek.go(a, -A: Kind(a), s: Stack) -> Maybe: match s: case S{xs}: match xs: case Nil{}: None{} case h <> t: Some{h} def Stack.peek(a, -A: Kind(a), s: Stack) -> Maybe: Stack.peek.go(a, A, s) def Stack.is_empty(a, -A: Kind(a), s: Stack) -> Bool: match s: case S{xs}: List.is_empty(a, A, xs) def Stack.length(a, -A: Kind(a), s: Stack) -> Nat: match s: case S{xs}: List.length(a, A, xs) def Stack.to_list(a, -A: Kind(a), s: Stack) -> List: match s: case S{xs}: xs def Stack.from_list(a, -A: Kind(a), xs: List) -> Stack: S{xs}