gonads/maybedoer.go

64 lines
1.2 KiB
Go

package gonads
import "errors"
var (
ErrOptionIsNone = errors.New("gonads: Option value contains nothing")
)
// Option is a container that might contain a value.
type Option[T any] struct {
val *T
}
// IsSome returns true if the option contains a value.
func (o Option[T]) IsSome() bool {
return o.val != nil
}
// IsNone returns false if the option does not contain a value.
func (o Option[T]) IsNone() bool {
return !o.IsSome()
}
// Take safely fetches the value from the Option.
func (o Option[T]) Take() (*T, error) {
if o.IsNone() {
return nil, ErrOptionIsNone
}
return o.val, nil
}
// Set assigns a value to an Option.
func (o *Option[T]) Set(val *T) {
o.val = val
}
func NewOption[T any](val *T) Option[T] {
return Option[T]{val: val}
}
// Thunk represents an uncomputed value that is cached for faster use later.
type Thunk[T any] struct {
o Option[T]
doer func() *T
}
// Force either returns the cached thunk value or computes it and caches the result.
func (t Thunk[T]) Force() *T {
if t.o.IsSome() {
return t.o.val
}
t.o.Set(t.doer())
return t.o.val
}
func NewThunk[T any](doer func() *T) Thunk[T] {
return Thunk[T]{
o: NewOption[T](nil),
doer: doer,
}
}