1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
pub mod kind {
// Renamed from hkt to kind to align with the Kind trait
//! # Kind-based Functor for the `monadify` library
//!
//! This module defines the `Functor` trait for types that implement the Kind pattern.
//! A Functor is a type constructor `F` (represented by a `Kind` marker)
//! that supports a `map` operation. This operation allows a function `A -> B`
//! to be applied to a value or values within a structure `F::Of<A>` (e.g., `Option<A>`),
//! resulting in a new structure `F::Of<B>` (e.g., `Option<B>`).
//!
//! The `Functor` trait is generic over:
//! - `Self`: The Kind marker (e.g., [`OptionKind`]).
//! - `A`: The input type of the value(s) within the Kind-encoded structure.
//! - `B`: The output type after applying the mapping function.
//!
//! It relies on the [`Kind1`] trait from `crate::kind_based::kind` to relate the
//! marker `Self` to its concrete type application `Self::Of<T>`.
use crate::function::{CFnOnce, RcFn};
use crate::kind_based::kind::{CFnOnceKind, Kind1, OptionKind, RcFnKind, ResultKind, VecKind};
use std::rc::Rc;
/// Represents a type constructor that can be mapped over, using the Kind pattern.
///
/// `Self` refers to the Kind marker type (e.g., [`OptionKind`], [`VecKind`])
/// that implements [`Kind1`].
///
/// The `map` operation takes an instance of `Self::Of<A>` (e.g., `Option<A>`)
/// and a function `A -> B`, producing `Self::Of<B>` (e.g., `Option<B>`).
///
/// ## Functor Laws
/// Implementors must satisfy two laws:
/// 1. **Identity**: For any Kind marker `F` and value `x: F::Of<A>`,
/// `F::map(x, |a| a) == x`.
/// 2. **Composition**: For any Kind marker `F`, value `x: F::Of<A>`, and functions
/// `f: A -> B`, `g: B -> C`,
/// `F::map(F::map(x, f), g) == F::map(x, |a| g(f(a)))`.
pub trait Functor<A, B>: Kind1 {
// A is input type, B is output type for map
/// Applies a function to a value (or values) within a Kind-encoded structure.
///
/// # Type Parameters
/// - `Self`: The Kind marker (e.g., [`OptionKind`]).
/// - `A`: The type of the value(s) inside the input structure `Self::Of<A>`.
/// - `B`: The type of the value(s) inside the output structure `Self::Of<B>`.
///
/// # Parameters
/// - `input`: The Kind-structured value, e.g., `Option<A>`, `Vec<A>`.
/// - `func`: A function to apply to the inner value(s).
/// The `FnMut(A) -> B + Clone + 'static` bound is chosen for broad compatibility:
/// - `FnMut`: Allows mutation of captured state if needed, and covers `Fn` and `FnOnce`
/// that don't consume their captures by value on first call. Standard library `map`
/// methods (like `Option::map`, `Result::map`) often take `FnOnce`.
/// - `Clone`: Necessary for some implementations like [`RcFnKind`], where the
/// function might need to be cloned if the resulting structure can be "called"
/// multiple times.
/// - `'static`: Often required when functions are stored or returned within structures
/// like [`RcFn`] or [`CFnOnce`], especially if they don't borrow from the local scope.
///
/// # Returns
/// A new Kind-structured value `Self::Of<B>` containing the result(s) of
/// applying `func`.
#[must_use]
fn map(input: Self::Of<A>, func: impl FnMut(A) -> B + Clone + 'static) -> Self::Of<B>;
}
impl<A, B> Functor<A, B> for OptionKind {
fn map(input: Self::Of<A>, func: impl FnMut(A) -> B + Clone + 'static) -> Self::Of<B> {
input.map(func) // Option::map takes FnOnce, FnMut is compatible
}
}
impl<A, B, E> Functor<A, B> for ResultKind<E> {
fn map(input: Self::Of<A>, func: impl FnMut(A) -> B + Clone + 'static) -> Self::Of<B> {
input.map(func) // Result::map takes FnOnce, FnMut is compatible
}
}
impl<A, B> Functor<A, B> for VecKind {
fn map(input: Self::Of<A>, func: impl FnMut(A) -> B + Clone + 'static) -> Self::Of<B> {
input.into_iter().map(func).collect()
}
}
// Functor impl for RcFnKind (maps over the output type of RcFn)
// A is the original output type, B is the new output type.
impl<X, A, B> Functor<A, B> for RcFnKind<X>
where
X: 'static,
A: 'static,
B: 'static,
{
/// Maps a function `A -> B` over the output of an `RcFn<X, A>`,
/// producing an `RcFn<X, B>`.
///
/// The inner `Rc` is cloned (O(1)) to capture the original function in
/// the new closure. `func` is `Clone`-d on each invocation to satisfy
/// the `Fn` (not `FnMut`) requirement of `Rc<dyn Fn>`.
fn map(input: Self::Of<A>, func: impl FnMut(A) -> B + Clone + 'static) -> Self::Of<B> {
let inner = input.0.clone();
RcFn(Rc::new(move |x: X| func.clone()(inner(x))))
}
}
// Functor impl for CFnOnceKind (maps over the output type of CFnOnce)
impl<X, A, B> Functor<A, B> for CFnOnceKind<X>
where
X: 'static,
A: 'static,
B: 'static, // B must be 'static for CFnOnce<X,B> which is Self::Of<B>
{
fn map(input: Self::Of<A>, mut func: impl FnMut(A) -> B + Clone + 'static) -> Self::Of<B> // Added mut for func
{
CFnOnce::new(move |x: X| func(input.call_once(x)))
}
}
}
// Directly export Kind-based Functor
pub use kind::Functor; // Renamed from hkt to kind
// Note: RcFnKind and CFnOnceKind are defined in kind_based::kind
// and Functor implementations for them are in the kind module above.
// This re-export makes `crate::functor::Functor` point to the Kind-based one.