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
//! # Wrapper Types
//!
//! This module provides various wrapper types that implement functional programming patterns
//! and algebraic structures. Wrappers enhance existing types with specific behaviors while
//! preserving their original functionality.
//!
//! ## Purpose
//!
//! Wrapper types serve several important purposes in functional programming:
//!
//! 1. **Algebraic Structures**: Implement mathematical structures like monoids and semigroups
//! 2. **Type-Based Operations**: Enable operations based on wrapped type (like Sum, Product)
//! 3. **Deferred Computation**: Allow for lazy evaluation with types like Thunk
//! 4. **Context Addition**: Add additional context or capabilities to basic types
//!
//! ## Available Wrapper Types
//!
//! ### Semigroup Wrappers
//!
//! These wrappers implement the `Semigroup` trait with specific combine operations:
//!
//! - `Sum<T>`: Forms a semigroup under addition (T must support `Add`)
//! - `Product<T>`: Forms a semigroup under multiplication (T must support `Mul`)
//! - `Min<T>`: Forms a semigroup taking the minimum value (T must support `PartialOrd`)
//! - `Max<T>`: Forms a semigroup taking the maximum value (T must support `PartialOrd`)
//!
//! ### Option-Based Wrappers
//!
//! These wrappers provide special handling for `Option` types:
//!
//! - `First<T>`: Takes the first `Some` value when combining multiple `Option<T>` values
//! - `Last<T>`: Takes the last `Some` value when combining multiple `Option<T>` values
//!
//! ### Computation Wrappers
//!
//! These wrappers provide different ways to handle computations:
//!
//! - `Thunk`: A lazy computation wrapper that evaluates only when needed
//! - `Memoizer`: Caches the result of a function for repeated calls
//!
//! ## Usage Patterns
//!
//! Wrapper types are typically used in these ways:
//!
//! ```rust
//! use rustica::datatypes::wrapper::sum::Sum;
//! use rustica::datatypes::wrapper::product::Product;
//! use rustica::traits::semigroup::Semigroup;
//!
//! // 1. Arithmetic with Sum/Product wrappers
//! let sum1: Sum<i32> = Sum(5);
//! let sum2: Sum<i32> = Sum(7);
//! let combined = sum1.combine(&sum2);
//! assert_eq!(combined.0, 12); // 5 + 7 = 12
//!
//! // 2. Combining multiple values into one
//! let values = vec![Sum(1), Sum(2), Sum(3)];
//! let sum: i32 = values.into_iter()
//! .fold(Sum(0), |acc, x| acc.combine(&x))
//! .0;
//! assert_eq!(sum, 6); // 1 + 2 + 3 = 6
//!
//! ```
//!
//! ## When to Use Wrapper Types
//!
//! - Use `Sum`/`Product` when working with numeric collections that need to be combined
//! - Use `Min`/`Max` for finding extremes in collections
//! - Use `First`/`Last` when dealing with optional values that need to be combined with precedence rules
//! - Use `Thunk` when you need lazy evaluation
//! - Use `Memoizer` when you want to cache function results
//!
//! ## Implementation Note
//!
//! Most wrapper types follow a simple pattern:
//!
//! 1. They store a single value of type T
//! 2. They implement relevant traits (Semigroup, Monoid, Functor, etc.)
//! 3. They provide methods to access the inner value
//!
//! This consistent interface makes it easy to understand and use these wrappers
//! in your own code.