Skip to main content

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 [`Arc`](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 [`Arc`](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/// 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 [`TryThunk`](crate::types::TryThunk).
124#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
125pub struct TryThunkBrand<E>(PhantomData<E>);
126
127/// Brand for [`TryLazy`](crate::types::TryLazy).
128#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
129pub struct TryLazyBrand<E, Config>(PhantomData<(E, Config)>);
130
131/// Brand for [`Vec`].
132#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
133pub struct VecBrand;