Skip to main content

Thunk

Struct Thunk 

Source
pub struct Thunk<'a, A>(/* private fields */);
Expand description

A deferred computation that produces a value of type A.

Thunk is NOT memoized - each call to Thunk::evaluate re-executes the computation. This type exists to build computation chains without allocation overhead.

Unlike Trampoline, Thunk does NOT require 'static and CAN implement HKT traits like Functor, Semimonad, etc.

§Trade-offs vs Trampoline

AspectThunk<'a, A>Trampoline<A>
HKT compatible✅ Yes❌ No (requires 'static)
Stack-safe⚠️ Partial (tail_rec_m only)✅ Yes (unlimited)
Lifetime'a (can borrow)'static only
Use caseGlue code, compositionDeep recursion, pipelines

§Algebraic Properties

Thunk is a proper Monad:

  • pure(a).evaluate() == a (left identity).
  • thunk.bind(pure) == thunk (right identity).
  • thunk.bind(f).bind(g) == thunk.bind(|a| f(a).bind(g)) (associativity).

§Type Parameters

  • A: The type of the value produced by the computation.

§Fields

  • 0: The closure that performs the computation.

§Examples

use fp_library::types::*;

let computation = Thunk::new(|| 5)
    .map(|x| x * 2)
    .map(|x| x + 1);

// No computation has happened yet!
// Only when we call evaluate() does it execute:
let result = computation.evaluate();
assert_eq!(result, 11);

Implementations§

Source§

impl<'a, A: 'a> Thunk<'a, A>

Source

pub fn new<F>(f: F) -> Self
where F: FnOnce() -> A + 'a,

Creates a new Thunk from a thunk.

§Type Signature

forall self. (() -> A) -> self

§Type Parameters
  • F: The type of the thunk.
§Parameters
  • f: The thunk to wrap.
§Returns

A new Thunk instance.

§Examples
use fp_library::types::*;

let thunk = Thunk::new(|| 42);
assert_eq!(thunk.evaluate(), 42);
Source

pub fn pure(a: A) -> Self
where A: 'a,

Returns a pure value (already computed).

§Type Signature

forall self. A -> self

§Parameters
  • a: The value to wrap.
§Returns

A new Thunk instance containing the value.

§Examples
use fp_library::{brands::*, functions::*, classes::*};

let thunk = pure::<ThunkBrand, _>(42);
assert_eq!(thunk.evaluate(), 42);
Source

pub fn defer<F>(f: F) -> Self
where F: FnOnce() -> Thunk<'a, A> + 'a,

Defers a computation that returns a Thunk.

§Type Signature

forall self. (() -> Thunk A) -> self

§Type Parameters
  • F: The type of the thunk.
§Parameters
  • f: The thunk that returns a Thunk.
§Returns

A new Thunk instance.

§Examples
use fp_library::{brands::*, functions::*, types::*};

let thunk = Thunk::defer(|| pure::<ThunkBrand, _>(42));
assert_eq!(thunk.evaluate(), 42);
Source

pub fn bind<B: 'a, F>(self, f: F) -> Thunk<'a, B>
where F: FnOnce(A) -> Thunk<'a, B> + 'a,

Monadic bind: chains computations.

Note: Each bind adds to the call stack. For deep recursion, use Trampoline instead.

§Type Signature

forall b. (A -> Thunk b) -> Thunk b

§Type Parameters
  • B: The type of the result of the new computation.
  • F: The type of the function to apply.
§Parameters
  • f: The function to apply to the result of the computation.
§Returns

A new Thunk instance representing the chained computation.

§Examples
use fp_library::{brands::*, functions::*};

let thunk = pure::<ThunkBrand, _>(21).bind(|x| pure::<ThunkBrand, _>(x * 2));
assert_eq!(thunk.evaluate(), 42);
Source

pub fn map<B: 'a, F>(self, f: F) -> Thunk<'a, B>
where F: FnOnce(A) -> B + 'a,

Functor map: transforms the result.

§Type Signature

forall b. (A -> b) -> Thunk b

§Type Parameters
  • B: The type of the result of the transformation.
  • F: The type of the transformation function.
§Parameters
  • f: The function to apply to the result of the computation.
§Returns

A new Thunk instance with the transformed result.

§Examples
use fp_library::{brands::*, functions::*};

let thunk = pure::<ThunkBrand, _>(21).map(|x| x * 2);
assert_eq!(thunk.evaluate(), 42);
Source

pub fn evaluate(self) -> A

Forces evaluation and returns the result.

§Type Signature

A

§Returns

The result of the computation.

§Examples
use fp_library::{brands::*, functions::*};

let thunk = pure::<ThunkBrand, _>(42);
assert_eq!(thunk.evaluate(), 42);

Trait Implementations§

Source§

impl<'a, A: 'a> Deferrable<'a> for Thunk<'a, A>

Source§

fn defer<F>(f: F) -> Self
where F: FnOnce() -> Self + 'a, Self: Sized,

Creates a Thunk from a computation that produces it.

§Type Signature

forall self. Deferrable self => (() -> self) -> self

§Type Parameters
  • F: The type of the thunk.
§Parameters
  • f: A thunk that produces the thunk.
§Returns

The deferred thunk.

§Examples
use fp_library::{brands::*, functions::*, types::*, classes::Deferrable};

let task: Thunk<i32> = Deferrable::defer(|| Thunk::pure(42));
assert_eq!(task.evaluate(), 42);
Source§

impl<'a, A, Config> From<Lazy<'a, A, Config>> for Thunk<'a, A>
where A: Clone + 'a, Config: LazyConfig,

Source§

fn from(lazy: Lazy<'a, A, Config>) -> Self

Converts to this type from the input type.
Source§

impl<'a, A> From<Thunk<'a, A>> for Lazy<'a, A, RcLazyConfig>

Source§

fn from(eval: Thunk<'a, A>) -> Self

Converts to this type from the input type.
Source§

impl<'a, A: 'a, E: 'a> From<Thunk<'a, A>> for TryThunk<'a, A, E>

Source§

fn from(eval: Thunk<'a, A>) -> Self

Converts to this type from the input type.
Source§

impl<'a, A: Monoid + 'a> Monoid for Thunk<'a, A>

Source§

fn empty() -> Self

Returns the identity Thunk.

§Type Signature

forall self. Monoid self => self

§Returns

A Thunk producing the identity value of A.

§Examples
use fp_library::{classes::*, types::*};

let t: Thunk<String> = Thunk::empty();
assert_eq!(t.evaluate(), "");
Source§

impl<'a, A: Semigroup + 'a> Semigroup for Thunk<'a, A>

Source§

fn append(a: Self, b: Self) -> Self

Combines two Thunks by combining their results.

§Type Signature

forall self. Semigroup self => (self, self) -> self

§Parameters
  • a: The first Thunk.
  • b: The second Thunk.
§Returns

A new Thunk containing the combined result.

§Examples
use fp_library::{brands::*, classes::*, functions::*};

let t1 = pure::<ThunkBrand, _>("Hello".to_string());
let t2 = pure::<ThunkBrand, _>(" World".to_string());
let t3 = append::<_>(t1, t2);
assert_eq!(t3.evaluate(), "Hello World");

Auto Trait Implementations§

§

impl<'a, A> Freeze for Thunk<'a, A>

§

impl<'a, A> !RefUnwindSafe for Thunk<'a, A>

§

impl<'a, A> !Send for Thunk<'a, A>

§

impl<'a, A> !Sync for Thunk<'a, A>

§

impl<'a, A> Unpin for Thunk<'a, A>

§

impl<'a, A> !UnwindSafe for Thunk<'a, A>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.