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§
Sourcefn 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>
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§
Sourcefn 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 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)));Sourcefn 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 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));Sourcefn 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<'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);Sourcefn 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
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 afterg).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§
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.
impl Extend for IdentityBrand
impl Extend for ThunkBrand
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.