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::{Category, CloneableFn, 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 [`Box`] unique ownership pointer.
34#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
35pub struct BoxBrand;
36
37/// Brand for [`CatList`](crate::types::CatList).
38#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct CatListBrand;
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/// Brand for [`Endomorphism`](crate::types::Endomorphism).
46#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
47pub struct EndomorphismBrand<CategoryBrand: Category, A>(PhantomData<(CategoryBrand, A)>);
48
49/// Brand for [`Thunk`](crate::types::Thunk).
50///
51/// Note: This is for `Thunk<'a, A>`, NOT for `Trampoline<A>`.
52/// `Trampoline` cannot implement HKT traits due to its `'static` requirement.
53#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
54pub struct ThunkBrand;
55
56/// Generic function brand parameterized by reference-counted pointer choice.
57#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
58pub struct FnBrand<PtrBrand: RefCountedPointer>(PhantomData<PtrBrand>);
59
60/// Brand for [`Free`](crate::types::Free).
61#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
62pub struct FreeBrand<F>(PhantomData<F>);
63
64/// Brand for [`Identity`](crate::types::Identity).
65#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
66pub struct IdentityBrand;
67
68/// Brand for [`Lazy`](crate::types::Lazy).
69#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
70pub struct LazyBrand<Config>(PhantomData<Config>);
71
72/// Brand for [`Option`].
73#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
74pub struct OptionBrand;
75
76/// Brand for [`Pair`](crate::types::Pair).
77#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
78pub struct PairBrand;
79
80/// Brand for the partially-applied form of [`Pair`](crate::types::Pair) with the first value filled in.
81#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
82pub struct PairWithFirstBrand<First>(First);
83
84/// Brand for the partially-applied form of [`Pair`](crate::types::Pair) with the second value filled in.
85#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
86pub struct PairWithSecondBrand<Second>(Second);
87
88/// Brand for [`Rc`](`std::rc::Rc`) reference-counted pointer.
89#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
90pub struct RcBrand;
91
92/// Brand for [reference-counted][std::rc::Rc] [closures][Fn]
93/// (`Rc<dyn Fn(A) -> B>`).
94///
95/// This type alias provides a way to construct and type-check [`Rc`](`std::rc::Rc`)-wrapped
96/// closures in a generic context.
97pub type RcFnBrand = FnBrand<RcBrand>;
98
99/// Brand for [`Result`].
100#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
101pub struct ResultBrand;
102
103/// Brand for the partially-applied form of [`Result`] with the [`Err`] constructor filled in.
104#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
105pub struct ResultWithErrBrand<E>(E);
106
107/// Brand for the partially-applied form of [`Result`] with the [`Ok`] constructor filled in.
108#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
109pub struct ResultWithOkBrand<T>(T);
110
111/// Brand for [`Step`](crate::types::Step).
112#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
113pub struct StepBrand;
114
115/// Brand for the partially-applied form of [`Step`](crate::types::Step) with the [`Loop`](crate::types::Step::Loop) type filled in.
116#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
117pub struct StepWithLoopBrand<A>(PhantomData<A>);
118
119/// Brand for the partially-applied form of [`Step`](crate::types::Step) with the [`Done`](crate::types::Step::Done) type filled in.
120#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
121pub struct StepWithDoneBrand<B>(PhantomData<B>);
122
123/// Brand for [`TryLazy`](crate::types::TryLazy).
124#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
125pub struct TryLazyBrand<E, Config>(PhantomData<(E, Config)>);
126
127/// Brand for [`TryThunk`](crate::types::TryThunk) (Bifunctor).
128#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
129pub struct TryThunkBrand;
130
131/// Brand for [`TryThunk`](crate::types::TryThunk) with the error value filled in (Functor over [`Ok`]).
132#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
133pub struct TryThunkWithErrBrand<E>(PhantomData<E>);
134
135/// Brand for [`TryThunk`](crate::types::TryThunk) with the success value filled in (Functor over [`Err`]).
136#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
137pub struct TryThunkWithOkBrand<A>(PhantomData<A>);
138
139/// Brand for [`Vec`].
140#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
141pub struct VecBrand;