fp_library/
brands.rs

1//! Higher-kinded representations of [types][crate::types].
2//!
3//! Brands represent higher-kinded (unapplied/partially-applied) forms of
4//! [types][crate::types], as opposed to concrete types, which are
5//! fully-applied.
6//!
7//! For example, [`VecBrand`] represents the higher-kinded type [`Vec`], whereas
8//! `Vec A`/`Vec<A>` is the concrete type where `Vec` has been applied to some
9//! generic type `A`.
10//!
11//! ### Examples
12//!
13//! ```
14//! use fp_library::{brands::*, functions::*};
15//!
16//! let x = Some(5);
17//! let y = map::<OptionBrand, _, _, _>(|i| i * 2, x);
18//! assert_eq!(y, Some(10));
19//! ```
20
21use crate::classes::{category::Category, clonable_fn::ClonableFn, once::Once};
22use std::marker::PhantomData;
23
24/// Brand for [atomically reference-counted][std::sync::Arc]
25/// [closures][Fn] (`Arc<dyn Fn(A) -> B>`).
26///
27/// This struct implements [`ClonableFn`] to provide a way to construct and
28/// type-check [`std::sync::Arc`]-wrapped closures in a generic context. The lifetime `'a`
29/// ensures the closure doesn't outlive referenced data, while `A` and `B`
30/// represent input and output types.
31#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
32pub struct ArcFnBrand;
33
34/// Brand for [`Endofunction`](crate::types::Endofunction).
35#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
36pub struct EndofunctionBrand<FnBrand: ClonableFn, A>(PhantomData<(FnBrand, A)>);
37
38/// Brand for [`Endomorphism`](crate::types::Endomorphism).
39#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
40pub struct EndomorphismBrand<CategoryBrand: Category, A>(PhantomData<(CategoryBrand, A)>);
41
42/// Brand for [`Identity`](crate::types::Identity).
43#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
44pub struct IdentityBrand;
45
46/// Brand for [`Lazy`](crate::types::Lazy).
47#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub struct LazyBrand<OnceBrand: Once, FnBrand: ClonableFn>(PhantomData<(OnceBrand, FnBrand)>);
49
50/// Brand for [`OnceCell`](std::cell::OnceCell).
51#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
52pub struct OnceCellBrand;
53
54/// Brand for [`OnceLock`](std::sync::OnceLock).
55#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
56pub struct OnceLockBrand;
57
58/// Brand for [`Option`].
59#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
60pub struct OptionBrand;
61
62/// Brand for [`Pair`](crate::types::Pair).
63#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
64pub struct PairBrand;
65
66/// Brand for the partially-applied form of [`Pair`](crate::types::Pair) with [the first value][crate::types::Pair] filled in.
67#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
68pub struct PairWithFirstBrand<First>(First);
69
70/// Brand for the partially-applied form of [`Pair`](crate::types::Pair) with [the second value][crate::types::Pair] filled in.
71#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
72pub struct PairWithSecondBrand<Second>(Second);
73
74/// Brand for [reference-counted][std::rc::Rc] [closures][Fn]
75/// (`Rc<dyn Fn(A) -> B>`).
76///
77/// This struct implements [`ClonableFn`] to provide a way to construct and
78/// type-check [`std::rc::Rc`]-wrapped closures in a generic context. The lifetime `'a`
79/// ensures the closure doesn't outlive referenced data, while `A` and `B`
80/// represent input and output types.
81#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
82pub struct RcFnBrand;
83
84/// Brand for [`Result`].
85#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
86pub struct ResultBrand;
87
88/// Brand for the partially-applied form of [`Result`] with the [`Err`] constructor filled in.
89#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
90pub struct ResultWithErrBrand<E>(E);
91
92/// Brand for the partially-applied form of [`Result`] with the [`Ok`] constructor filled in.
93#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
94pub struct ResultWithOkBrand<T>(T);
95
96/// Brand for [`Vec`].
97#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
98pub struct VecBrand;