go-scopes/lib/funky/funky.go

72 lines
1.2 KiB
Go

// 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 {
Maybe[V]
Next() Maybe[V]
}
type sliceIt[V any] struct {
idx int
slice []V
}
func SliceIterator[V any](sl []V) Iterator[V] {
return &sliceIt[V]{slice: sl}
}
func (it *sliceIt[V]) Next() Maybe[V] {
if it.IsNothing() {
return Nothing[V]()
}
v := it.Value()
it.idx++
return Just(v)
}
func (it *sliceIt[V]) IsNothing() bool {
return it.idx >= len(it.slice)
}
func (it *sliceIt[V]) Value() V {
return 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
}