// Package funky provides a few constructs usually present in pure // functional programming environments, using Go 1.18 generics. package funky // Maybe (sometimes called `Option`) type Maybe[V any] interface { IsNothing() bool Value() V } type maybe[V any] struct { isNothing bool value V } func Nothing[V any]() Maybe[V] { return &maybe[V]{isNothing: true} } func Just[V any](v V) Maybe[V] { return &maybe[V]{false, v} } func (m *maybe[V]) IsNothing() bool { return m.isNothing } func (m *maybe[V]) Value() V { return m.value } // Iterator type Iterator[V any] interface { Next() Maybe[V] } type sliceIt[V any] struct { idx int slice []V } func SliceIterator[V any](sl []V) Iterator[V] { return &sliceIt[V]{-1, sl} } func (it *sliceIt[V]) Next() Maybe[V] { if it.idx >= len(it.slice)-1 { return Nothing[V]() } it.idx++ return Just(it.slice[it.idx]) } func Slice[V any](it Iterator[V]) []V { var out []V for m := it.Next(); !m.IsNothing(); m = it.Next() { out = append(out, m.Value()) } return out }