# NonEmpty (aka NEList) — foundational non-empty list for Bend. # Publish entry for this package. Depends only on Base (does not reimplement List). # # Encoding: head + List tail. Emptiness is unrepresentable by construction. # Quantity: NonEmpty is Kind(a), same convention as List/Maybe. import Base type NonEmpty is Kind(a): NE{head: A, tail: List} def NonEmpty.one(a, -A: Kind(a), x: A) -> NonEmpty: NE{x, Nil{}} def NonEmpty.cons(a, -A: Kind(a), x: A, xs: NonEmpty) -> NonEmpty: match xs: case NE{h, t}: NE{x, h <> t} def NonEmpty.from_list(a, -A: Kind(a), xs: List) -> Maybe>: match xs: case Nil{}: None{} case h <> t: Some{NE{h, t}} def NonEmpty.to_list(a, -A: Kind(a), xs: NonEmpty) -> List: match xs: case NE{h, t}: h <> t def NonEmpty.head(a, -A: Kind(a), xs: NonEmpty) -> A: match xs: case NE{h, t}: h def NonEmpty.tail(a, -A: Kind(a), xs: NonEmpty) -> List: match xs: case NE{h, t}: t def NonEmpty.length(a, -A: Kind(a), xs: NonEmpty) -> Nat: match xs: case NE{h, t}: 1n+List.length(a, A, t) # Template map, same shape as List.map (affine NonEmpty = NonEmpty<&1, A>). def NonEmpty.map(~A: Type, ~B: Type, ~f: A -> B, xs: NonEmpty) -> NonEmpty: match xs: case NE{h, t}: NE{f(h), List.map(~A, ~B, ~f, t)} def NonEmpty.append(a, -A: Kind(a), xs: NonEmpty, ys: NonEmpty) -> NonEmpty: match xs: case NE{h, t}: match ys: case NE{yh, yt}: NE{h, List.append(a, A, t, yh <> yt)} def NonEmpty.snoc(a, -A: Kind(a), xs: NonEmpty, y: A) -> NonEmpty: match xs: case NE{h, t}: NE{h, List.append(a, A, t, y <> Nil{})}