# Architecture & Design Decisions
This document records architectural decisions and design patterns used in `fp-library`.
## 1. Module Organization
### 1.1. Brand Structs (Centralized)
**Decision:**
Brand structs (e.g., `OptionBrand`) are **centralized** in `src/brands.rs`.
**Reasoning:**
- **Leaf Nodes:** In the dependency graph, Brand structs are **leaf nodes**; they have no outgoing edges (dependencies) to other modules in the crate.
- **Graph Stability:** Centralizing these leaf nodes in `brands.rs` creates a stable foundation. Higher-level modules (like `types/*.rs`) can import from this common sink without creating back-edges or cycles.
### 1.2. Free Functions (Distributed)
**Decision:**
Free function wrappers (e.g., `map`, `pure`) are **defined in their trait's module** (e.g., `src/classes/functor.rs`) and re-exported in `src/functions.rs`.
**Reasoning:**
- **Downstream Dependencies:** Free function wrappers are **downstream nodes**; they depend on (have outgoing edges to) the trait definitions.
- **Cycle Prevention:** `functions.rs` also contains generic helpers (like `compose`) which are **leaf nodes**. If we defined the downstream wrappers in `functions.rs`, the file would effectively become both upstream _and_ downstream of the trait modules. This would create **bidirectional dependencies** (cycles) if a trait module ever needed to import a helper.
- **Facade Pattern:** `functions.rs` acts as a **facade**, re-exporting symbols to provide a unified API surface without coupling the underlying definition graph.
## 2. Documentation & Examples
Documentation structure (sections, headings, parameter ordering) is enforced by the documentation macros in `fp-macros/src/documentation/` (`#[document_module]`, `#[document_signature]`, `#[document_type_parameters]`, `#[document_parameters]`, `#[document_returns]`, `#[document_examples]`). All modules should use `#[document_module]`. See `fp-macros/src/lib.rs` for usage.
This section covers content quality guidelines that the macros cannot enforce.
### 2.1. Type Signature Content
The type signature generated by `#[document_signature]` must accurately reflect the code. Contributors should verify:
- Signatures correctly indicate uncurried semantics (the library's standard).
- Brand type parameters are replaced with their corresponding concrete types for clarity. Write `Result e` not `ResultWithErrBrand e`.
- Quantifiers are accurate, correctly ordered (matching the code), and omit unused variables for clarity.
### 2.2. Example Content
Examples should demonstrate the library's intended usage patterns:
- Import items using grouped wildcards (`use fp_library::{brands::*, functions::*}`) instead of individually by name.
- Use free-function versions of trait methods with as many turbofish holes as possible (`map::<OptionBrand, _, _, _>(|x| x * 2, Some(5))`) instead of calling trait methods directly (`OptionBrand::map(...)`).
**Reasoning:** The library is designed to be used via free functions with partial type inference. Examples must demonstrate this pattern to educate users on the ergonomic benefits.