Skip to main content

Extend

Trait Extend 

Source
pub trait Extend: Functor {
    // Required method
    fn extend<'a, A: 'a + Clone, B: 'a>(
        f: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>) -> B + 'a,
        wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>,
    ) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, B>;

    // Provided methods
    fn duplicate<'a, A: 'a + Clone>(
        wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>,
    ) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>>
       where <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>: 'a { ... }
    fn extend_flipped<'a, A: 'a + Clone, B: 'a>(
        wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>,
        f: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>) -> B + 'a,
    ) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, B> { ... }
    fn compose_co_kleisli<'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
        f: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>) -> B + 'a,
        g: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, B>) -> C + 'a,
        wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>,
    ) -> C { ... }
    fn compose_co_kleisli_flipped<'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
        f: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, B>) -> C + 'a,
        g: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>) -> B + 'a,
        wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>,
    ) -> C { ... }
}
Expand description

A type class for types that support co-Kleisli extension.

Extend is the dual of Semimonad. Where bind : (A -> F<B>) -> F<A> -> F<B> feeds a single extracted value into a function that produces a new context, extend : (F<A> -> B) -> F<A> -> F<B> feeds an entire context into a function and re-wraps the result.

class Functor w <= Extend w

§Laws

Associativity: composing two extensions is the same as extending with a pre-composed function.

For any f: F<B> -> C and g: F<A> -> B:

extend(f, extend(g, w)) == extend(|w| f(extend(g, w)), w)

This is dual to the associativity law for bind.

§Note on LazyBrand

LazyBrand cannot implement Extend because Extend: Functor and LazyBrand cannot implement Functor (its evaluate returns &A, not owned A). PureScript’s Lazy has Extend/Comonad because GC provides owned values from force. In this library, ThunkBrand fills the Functor + Extend + Comonad role for lazy types, while LazyBrand provides memoization via RefFunctor.

§Examples

Associativity law for Vec:

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

let w = vec![1, 2, 3];
let f = |v: Vec<i32>| v.iter().sum::<i32>();
let g = |v: Vec<i32>| v.len() as i32;

// extend(f, extend(g, w)) == extend(|w| f(extend(g, w)), w)
let lhs = extend::<VecBrand, _, _>(f, extend::<VecBrand, _, _>(g, w.clone()));
let rhs = extend::<VecBrand, _, _>(|w| f(extend::<VecBrand, _, _>(g, w)), w);
assert_eq!(lhs, rhs);

Required Methods§

Source

fn extend<'a, A: 'a + Clone, B: 'a>( f: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>) -> B + 'a, wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>, ) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, B>

Extends a local context-dependent computation to a global computation.

Given a function that consumes an F<A> and produces a B, and a value of type F<A>, produces an F<B> by applying the function in a context-sensitive way.

§Type Signature

forall A B. (Self A -> B, Self A) -> Self B

§Type Parameters
  • 'a: The lifetime of the values.
  • A: The type of the value(s) inside the comonadic context.
  • B: The result type of the extension function.
§Parameters
  • f: The function that consumes a whole context and produces a value.
  • wa: The comonadic context to extend over.
§Returns

A new comonadic context containing the results of applying the function.

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

let result = IdentityBrand::extend(|id: Identity<i32>| id.0 * 2, Identity(5));
assert_eq!(result, Identity(10));

Provided Methods§

Source

fn duplicate<'a, A: 'a + Clone>( wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>, ) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>>
where <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>: 'a,

Duplicates a comonadic context, wrapping it inside another layer of the same context.

duplicate(wa) is equivalent to extend(identity, wa). It is the dual of join for monads.

Produces F<F<A>> from F<A>, embedding the original context as the inner value.

§Type Signature

forall A. Self A -> Self (Self A)

§Type Parameters
  • 'a: The lifetime of the values.
  • A: The type of the value(s) inside the comonadic context.
§Parameters
  • wa: The comonadic context to duplicate.
§Returns

A doubly-wrapped comonadic context.

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

let result = IdentityBrand::duplicate(Identity(5));
assert_eq!(result, Identity(Identity(5)));
Source

fn extend_flipped<'a, A: 'a + Clone, B: 'a>( wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>, f: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>) -> B + 'a, ) -> <Self as Kind_cdc7cd43dac7585f>::Of<'a, B>

Extends with the arguments flipped.

A version of extend where the comonadic context comes first, followed by the extension function.

§Type Signature

forall A B. (Self A, Self A -> B) -> Self B

§Type Parameters
  • 'a: The lifetime of the values.
  • A: The type of the value(s) inside the comonadic context.
  • B: The result type of the extension function.
§Parameters
  • wa: The comonadic context to extend over.
  • f: The function that consumes a whole context and produces a value.
§Returns

A new comonadic context containing the results of applying the function.

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

let result = IdentityBrand::extend_flipped(Identity(5), |id| id.0 * 3);
assert_eq!(result, Identity(15));
Source

fn compose_co_kleisli<'a, A: 'a + Clone, B: 'a + Clone, C: 'a>( f: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>) -> B + 'a, g: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, B>) -> C + 'a, wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>, ) -> C

Forwards co-Kleisli composition.

Composes two co-Kleisli functions left-to-right: first applies f via extend, then applies g to the result. This is the dual of compose_kleisli.

§Type Signature

forall A B C. (Self A -> B, Self B -> C, Self A) -> C

§Type Parameters
  • 'a: The lifetime of the values.
  • A: The type of the value(s) inside the comonadic context.
  • B: The result type of the first co-Kleisli function.
  • C: The result type of the second co-Kleisli function.
§Parameters
  • f: The first co-Kleisli function.
  • g: The second co-Kleisli function.
  • wa: The comonadic context to operate on.
§Returns

The result of composing both co-Kleisli functions and applying them to the context.

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

let f = |id: Identity<i32>| id.0 + 1;
let g = |id: Identity<i32>| id.0 * 10;
let result = IdentityBrand::compose_co_kleisli(f, g, Identity(5));
assert_eq!(result, 60);
Source

fn compose_co_kleisli_flipped<'a, A: 'a + Clone, B: 'a + Clone, C: 'a>( f: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, B>) -> C + 'a, g: impl Fn(<Self as Kind_cdc7cd43dac7585f>::Of<'a, A>) -> B + 'a, wa: <Self as Kind_cdc7cd43dac7585f>::Of<'a, A>, ) -> C

Backwards co-Kleisli composition.

Composes two co-Kleisli functions right-to-left: first applies g via extend, then applies f to the result. This is the dual of compose_kleisli_flipped.

§Type Signature

forall A B C. (Self B -> C, Self A -> B, Self A) -> C

§Type Parameters
  • 'a: The lifetime of the values.
  • A: The type of the value(s) inside the comonadic context.
  • B: The result type of the second co-Kleisli function (applied first).
  • C: The result type of the first co-Kleisli function (applied second).
§Parameters
  • f: The second co-Kleisli function (applied after g).
  • g: The first co-Kleisli function (applied first to the context).
  • wa: The comonadic context to operate on.
§Returns

The result of composing both co-Kleisli functions and applying them to the context.

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

let f = |id: Identity<i32>| id.0 * 10;
let g = |id: Identity<i32>| id.0 + 1;
let result = IdentityBrand::compose_co_kleisli_flipped(f, g, Identity(5));
assert_eq!(result, 60);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl Extend for CatListBrand

Cooperative extension for CatList, following the same suffix semantics as the PureScript Extend Array instance.

extend(f, list) produces a new list where each element is f applied to the suffix of the original list starting at that position. Requires A: Clone because suffixes are materialized as owned lists.

Source§

impl Extend for IdentityBrand

Source§

impl Extend for ThunkBrand

Source§

impl Extend for VecBrand

Cooperative extension for Vec, ported from PureScript’s Extend Array instance.

extend(f, vec) produces a new vector where each element at index i is f applied to the suffix vec[i..]. This is the dual of Semimonad::bind: where bind feeds each element into a function that produces a new context, extend feeds each suffix (context) into a function that produces a single value.

Requires A: Clone because suffixes are materialized as owned vectors.