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
/*
* SPDX-License-Identifier: MIT
* Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
*/
//! The lazy IO effect: a deferred description of an input/output computation.
//!
//! IO is the workspace's first genuinely side-effecting effect. Every other effect in the family
//! (the `Error`/`Log`/`State` channels of `CausalEffectPropagationProcess`, the `Effect3/4/5`
//! type-encoded effect system) is *pure* — a fixed type parameter threading **data** through a
//! computation, performing no real-world side effect. IO is different: it executes a **real** effect,
//! so its execution must be deferred to the program edge.
//!
//! # Encoding: the Arrow twin, not a witnessed container
//!
//! A lazy, mono-parametric `Io<A>` (the shape the witness [`Monad`](crate::Monad) trait requires —
//! `F::Type<A>` has one hole) cannot store data-dependent continuations without `Box<dyn FnOnce>`,
//! which this workspace forbids. So IO is realized exactly the way the [`Arrow`](crate::Arrow)
//! algebra is realized: an [`IoAction`] trait whose combinators return **new concrete types**
//! ([`IoMap`], [`IoAndThen`], [`IoMapErr`]). Composition is total and monomorphized, with **no
//! `dyn`, no trait objects, no macros**. An `IoAction` is a nullary arrow `() ⇝ A` in the
//! [`Kleisli`](crate::Kleisli) category of `Result`.
//!
//! The whole module is `no_std`-safe: it uses only `core` (`Result`, closures, `PhantomData`).
//! Concrete file actions (and the filesystem effect itself) live in `deep_causality_core` behind its
//! `std` feature; this layer is generic over the error type so haft names no concrete error.
//!
//! # Laws
//!
//! `IoAction` is a monad; its `and_then` is composition in the [`Kleisli`](crate::Kleisli) category
//! of `Result`. With `pure`/`and_then`/`map`:
//!
//! 1. **Left identity:** `pure(a).and_then(f)` ≡ `f(a)`
//! 2. **Right identity:** `m.and_then(pure)` ≡ `m`
//! 3. **Associativity:** `m.and_then(f).and_then(g)` ≡ `m.and_then(|x| f(x).and_then(g))`
//!
//! (Equivalences hold on the value produced by [`IoAction::run`].)
pub use IoAndThen;
pub use ;
pub use IoMap;
pub use IoMapErr;
pub use ;
/// A deferred description of an input/output computation.
///
/// Constructing an `IoAction` or composing it with [`map`](IoAction::map) /
/// [`and_then`](IoAction::and_then) / [`map_err`](IoAction::map_err) performs **no** side effect.
/// [`run`](IoAction::run) is the only operation permitted to perform one, and it consumes the action
/// (an IO action runs once, at the program edge).
///
/// The combinator methods are provided; an implementor supplies only `Output`, `Error`, and `run`.