gonads/thunk.go

39 lines
1.0 KiB
Go

package gonads
// Thunk contains a partially computed value. This thunk is also lazy because
// it will only run the underlying thunked action _once_ and then return the
// result of that action, caching it for further use.
//
// If this is confusing to you, consider the following JavaScript:
//
// let add = (x, y) => x + y;
// let addCurr = (x) => (y) => x + y;
// console.log(add(2, 2)); // 4
// console.log(addCurr(2)(2)); // 4
// let addTwo = addCurr(2); // (y) => 2 + y;
//
// In this example, `addTwo` is a thunk that contains a partially applied addCurr
// invocation.
type Thunk[T any] struct {
doer func() T // action being thunked
o *Option[T] // cache for complete thunk data
}
// Force evaluates a Thunk's action if it needs to, otherwise it returns the
// previously evaluated result.
func (t Thunk[T]) Force() T {
if t.o.IsSome() {
return t.o.Yank()
}
t.o.Set(t.doer())
return t.o.Yank()
}
func NewThunk[T any](doer func() T) *Thunk[T] {
return &Thunk[T]{
doer: doer,
o: NewOption[T](),
}
}