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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! # Identity Monad
// HKT version is now default.
// Classic comments might still offer some insight but primary focus is HKT.
pub mod hkt {
//! # Higher-Kinded Type (HKT) Identity Monad
//!
//! This module provides the HKT implementation of the `Identity` monad.
//! The `Identity` monad is the simplest monad; it just wraps a value without
//! adding any computational context beyond the wrapping itself.
//!
//! It's often used as a base for monad transformers or to make non-monadic
//! code fit into a monadic interface.
//!
//! ## Key Components
//! - [`Identity<A>`]: The wrapper struct holding a value of type `A`.
//! - [`IdentityHKTMarker`]: The HKT marker for `Identity`.
//!
//! ## Example
//! ```
//! use monadify::identity::hkt::{Identity, IdentityHKTMarker};
//! use monadify::functor::hkt::Functor;
//! use monadify::applicative::hkt::Applicative;
//! use monadify::monad::hkt::{Bind, Monad};
//!
//! // Pure (from Applicative)
//! let id_val: Identity<i32> = IdentityHKTMarker::pure(10);
//! assert_eq!(id_val, Identity(10));
//!
//! // Map (from Functor)
//! let mapped_id: Identity<String> = IdentityHKTMarker::map(id_val, |x| (x * 2).to_string());
//! assert_eq!(mapped_id, Identity("20".to_string()));
//!
//! // Bind
//! let bound_id: Identity<f64> = IdentityHKTMarker::bind(mapped_id, |s| Identity(s.len() as f64));
//! assert_eq!(bound_id, Identity(2.0));
//!
//! // Join (from Monad)
//! let nested_id: Identity<Identity<i32>> = Identity(Identity(100));
//! let joined_id: Identity<i32> = IdentityHKTMarker::join(nested_id);
//! assert_eq!(joined_id, Identity(100));
//! ```
use crate::kind_based::kind::HKT;
use crate::functor::hkt as functor_hkt;
use crate::apply::hkt as apply_hkt;
use crate::applicative::hkt as applicative_hkt;
use crate::monad::hkt as monad_hkt;
use crate::function::CFn; // For Apply's function container
/// A simple wrapper struct that holds a value of type `A`.
///
/// This is the core data type for the `Identity` monad. It doesn't add
/// any special context other than simply containing the value.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Identity<A>(pub A);
/// The HKT marker for the `Identity` monad.
///
/// This unit struct is used to implement the HKT traits (`Functor`, `Apply`,
/// `Applicative`, `Monad`, `Bind`) for `Identity`.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct IdentityHKTMarker;
impl HKT for IdentityHKTMarker {
type Applied<T> = Identity<T>;
}
// HKT1 is implemented by the blanket impl in kind.rs for types that impl HKT.
// HKT Functor for IdentityHKTMarker
impl<A, B> functor_hkt::Functor<A, B> for IdentityHKTMarker
where
// A: 'static, B: 'static are not strictly needed here if func is FnMut
// but the trait itself might impose them for broader compatibility.
// The functor::Functor trait itself does not require 'static for A, B.
{
/// Applies a function to the value inside `Identity`.
/// `Identity(a)` becomes `Identity(func(a))`.
fn map(input: Identity<A>, mut func: impl FnMut(A) -> B) -> Identity<B> {
Identity(func(input.0))
}
}
// HKT Apply for IdentityHKTMarker
impl<A, B> apply_hkt::Apply<A, B> for IdentityHKTMarker
where
A: 'static, // Required by Apply trait definition
B: 'static, // Required by Apply trait definition
{
/// Applies a wrapped function `Identity<CFn<A, B>>` to a wrapped value `Identity<A>`.
fn apply(
value_container: Identity<A>,
function_container: Identity<CFn<A, B>>,
) -> Identity<B> {
Identity(function_container.0.call(value_container.0))
}
}
// HKT Applicative for IdentityHKTMarker
impl<T: 'static> applicative_hkt::Applicative<T> for IdentityHKTMarker
// T: 'static is already on the Applicative trait
{
/// Lifts a value `T` into `Identity<T>`.
fn pure(value: T) -> Identity<T> {
Identity(value)
}
}
// HKT Bind for IdentityHKTMarker
impl<A, B> monad_hkt::Bind<A, B> for IdentityHKTMarker
where
A: 'static, // Required by Bind trait definition
B: 'static, // Required by Bind trait definition
{
/// Applies a function `A -> Identity<B>` to the value inside `Identity<A>`.
/// Effectively, it unwraps the value, applies the function, and returns the new `Identity<B>`.
fn bind(input: Identity<A>, mut func: impl FnMut(A) -> Identity<B>) -> Identity<B> {
func(input.0)
}
}
// HKT Monad for IdentityHKTMarker
impl<A: 'static> monad_hkt::Monad<A> for IdentityHKTMarker {
/// Flattens `Identity<Identity<A>>` to `Identity<A>`.
/// This simply unwraps the outer `Identity`.
fn join(mma: Identity<Identity<A>>) -> Identity<A> {
// mma is Identity(Identity(value))
// mma.0 is Identity(value)
// So, we return mma.0 directly.
// However, the original code `Identity(mma.0.0)` is also correct
// as it constructs a new Identity from the innermost value.
// Let's stick to the simpler `mma.0` if it means the same type.
// `mma.0` is `Identity<A>`, which is `Self::Applied<A>`.
// `Identity(mma.0.0)` is also `Identity<A>`. Both are fine.
// The original `Identity(mma.0.0)` is perhaps more explicit about reconstruction.
mma.0 // This is Identity<A>
// Or, more explicitly: Identity(mma.0.0)
}
}
}
// Directly export HKT Identity and its marker
pub use hkt::{Identity, IdentityHKTMarker};
// Note: HKT1 is imported within the hkt module.