62 lines
1 KiB
Go
62 lines
1 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 {
|
|
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
|
|
}
|