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::{
22	category::Category, cloneable_fn::CloneableFn, ref_counted_pointer::RefCountedPointer,
23};
24use std::marker::PhantomData;
25
26/// Brand for [`std::sync::Arc`] atomic reference-counted pointer.
27#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
28pub struct ArcBrand;
29
30/// Brand for [atomically reference-counted][std::sync::Arc]
31/// [closures][Fn] (`Arc<dyn Fn(A) -> B>`).
32///
33/// This type alias provides a way to construct and type-check [`std::sync::Arc`]-wrapped
34/// closures in a generic context.
35pub type ArcFnBrand = FnBrand<ArcBrand>;
36
37/// Brand for [`Box`] unique ownership pointer.
38#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct BoxBrand;
40
41/// Brand for [`Endofunction`](crate::types::Endofunction).
42#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
43pub struct EndofunctionBrand<FnBrand: CloneableFn, A>(PhantomData<(FnBrand, A)>);
44
45/// Generic function brand parameterized by reference-counted pointer choice.
46#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
47pub struct FnBrand<PtrBrand: RefCountedPointer>(PhantomData<PtrBrand>);
48
49/// Brand for [`Endomorphism`](crate::types::Endomorphism).
50#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
51pub struct EndomorphismBrand<CategoryBrand: Category, A>(PhantomData<(CategoryBrand, A)>);
52
53/// Brand for [`Identity`](crate::types::Identity).
54#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
55pub struct IdentityBrand;
56
57/// Brand for [`Lazy`](crate::types::Lazy).
58#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
59pub struct LazyBrand<Config>(PhantomData<Config>);
60
61/// Brand for [`OnceCell`](std::cell::OnceCell).
62#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
63pub struct OnceCellBrand;
64
65/// Brand for [`OnceLock`](std::sync::OnceLock).
66#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
67pub struct OnceLockBrand;
68
69/// Brand for [`Option`].
70#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
71pub struct OptionBrand;
72
73/// Brand for [`Pair`](crate::types::Pair).
74#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
75pub struct PairBrand;
76
77/// Brand for the partially-applied form of [`Pair`](crate::types::Pair) with the first value filled in.
78#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
79pub struct PairWithFirstBrand<First>(First);
80
81/// Brand for the partially-applied form of [`Pair`](crate::types::Pair) with the second value filled in.
82#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
83pub struct PairWithSecondBrand<Second>(Second);
84
85/// Brand for [`Rc`](`std::rc::Rc`) reference-counted pointer.
86#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
87pub struct RcBrand;
88
89/// Brand for [reference-counted][std::rc::Rc] [closures][Fn]
90/// (`Rc<dyn Fn(A) -> B>`).
91///
92/// This type alias provides a way to construct and type-check [`Rc`](`std::rc::Rc`)-wrapped
93/// closures in a generic context.
94pub type RcFnBrand = FnBrand<RcBrand>;
95
96/// Brand for [`Result`].
97#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
98pub struct ResultBrand;
99
100/// Brand for the partially-applied form of [`Result`] with the [`Err`] constructor filled in.
101#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
102pub struct ResultWithErrBrand<E>(E);
103
104/// Brand for the partially-applied form of [`Result`] with the [`Ok`] constructor filled in.
105#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
106pub struct ResultWithOkBrand<T>(T);
107
108/// Brand for [`Vec`].
109#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
110pub struct VecBrand;