Skip to main content

fp_library/
brands.rs

1//! Brands represent higher-kinded (unapplied/partially-applied) forms of
2//! [types][crate::types], as opposed to concrete types, which are
3//! fully-applied.
4//!
5//! For example, [`VecBrand`] represents the higher-kinded type [`Vec`], whereas
6//! `Vec A`/`Vec<A>` is the concrete type where `Vec` has been applied to some
7//! generic type `A`.
8//!
9//! ### Examples
10//!
11//! ```
12//! use fp_library::{brands::*, functions::*};
13//!
14//! let x = Some(5);
15//! let y = map::<OptionBrand, _, _, _>(|i| i * 2, x);
16//! assert_eq!(y, Some(10));
17//! ```
18
19use crate::classes::RefCountedPointer;
20use std::marker::PhantomData;
21
22/// Brand for [`Arc`](std::sync::Arc) atomic reference-counted pointer.
23#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct ArcBrand;
25
26/// Brand for [atomically reference-counted][std::sync::Arc]
27/// [closures][Fn] (`Arc<dyn Fn(A) -> B>`).
28///
29/// This type alias provides a way to construct and type-check [`Arc`](std::sync::Arc)-wrapped
30/// closures in a generic context.
31pub type ArcFnBrand = FnBrand<ArcBrand>;
32
33/// Brand for [`CatList`](crate::types::CatList).
34#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
35pub struct CatListBrand;
36
37/// Brand for [`Thunk`](crate::types::Thunk).
38///
39/// Note: This is for `Thunk<'a, A>`, NOT for `Trampoline<A>`.
40/// `Trampoline` cannot implement HKT traits due to its `'static` requirement.
41#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
42pub struct ThunkBrand;
43
44/// Generic function brand parameterized by reference-counted pointer choice.
45#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
46pub struct FnBrand<PtrBrand: RefCountedPointer>(PhantomData<PtrBrand>);
47
48/// Brand for [`Identity`](crate::types::Identity).
49#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
50pub struct IdentityBrand;
51
52/// Brand for [`Lazy`](crate::types::Lazy).
53#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
54pub struct LazyBrand<Config>(PhantomData<Config>);
55
56/// Brand for [`Option`].
57#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
58pub struct OptionBrand;
59
60/// Brand for [`Pair`](crate::types::Pair).
61#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
62pub struct PairBrand;
63
64/// Brand for the partially-applied form of [`Pair`](crate::types::Pair) with the first value filled in.
65#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
66pub struct PairWithFirstBrand<First>(First);
67
68/// Brand for the partially-applied form of [`Pair`](crate::types::Pair) with the second value filled in.
69#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
70pub struct PairWithSecondBrand<Second>(Second);
71
72/// Brand for [`Rc`](`std::rc::Rc`) reference-counted pointer.
73#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
74pub struct RcBrand;
75
76/// Brand for [reference-counted][std::rc::Rc] [closures][Fn]
77/// (`Rc<dyn Fn(A) -> B>`).
78///
79/// This type alias provides a way to construct and type-check [`Rc`](`std::rc::Rc`)-wrapped
80/// closures in a generic context.
81pub type RcFnBrand = FnBrand<RcBrand>;
82
83/// Brand for [`Result`].
84#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
85pub struct ResultBrand;
86
87/// Brand for the partially-applied form of [`Result`] with the [`Err`] constructor filled in.
88#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
89pub struct ResultWithErrBrand<E>(E);
90
91/// Brand for the partially-applied form of [`Result`] with the [`Ok`] constructor filled in.
92#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
93pub struct ResultWithOkBrand<T>(T);
94
95/// Brand for [`Step`](crate::types::Step).
96#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
97pub struct StepBrand;
98
99/// Brand for the partially-applied form of [`Step`](crate::types::Step) with the [`Loop`](crate::types::Step::Loop) type filled in.
100#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
101pub struct StepWithLoopBrand<A>(PhantomData<A>);
102
103/// Brand for the partially-applied form of [`Step`](crate::types::Step) with the [`Done`](crate::types::Step::Done) type filled in.
104#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
105pub struct StepWithDoneBrand<B>(PhantomData<B>);
106
107/// Brand for [`TryLazy`](crate::types::TryLazy).
108#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
109pub struct TryLazyBrand<E, Config>(PhantomData<(E, Config)>);
110
111/// Brand for [`TryThunk`](crate::types::TryThunk) (Bifunctor).
112#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
113pub struct TryThunkBrand;
114
115/// Brand for [`TryThunk`](crate::types::TryThunk) with the error value filled in (Functor over [`Ok`]).
116#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
117pub struct TryThunkWithErrBrand<E>(PhantomData<E>);
118
119/// Brand for [`TryThunk`](crate::types::TryThunk) with the success value filled in (Functor over [`Err`]).
120#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
121pub struct TryThunkWithOkBrand<A>(PhantomData<A>);
122
123/// Brand for `(A,)`, with A not filled in.
124#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
125pub struct Tuple1Brand;
126
127/// Brand for `(First, Second)`, with neither `First` nor `Second` filled in.
128#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
129pub struct Tuple2Brand;
130
131/// Brand for `(First, Second)`, with `First` filled in (Functor over `Second`).
132#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
133pub struct Tuple2WithFirstBrand<First>(First);
134
135/// Brand for `(First, Second)`, with `Second` filled in (Functor over `First`).
136#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
137pub struct Tuple2WithSecondBrand<Second>(Second);
138
139/// Brand for [`Vec`].
140#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
141pub struct VecBrand;