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](), } }