64 lines
1.2 KiB
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,
|
|
}
|
|
}
|