1use std::cell::OnceCell;
6use std::sync::{Arc, OnceLock};
7
8use super::functions::*;
9use std::collections::VecDeque;
10
11pub enum LazyList<A> {
13 Nil,
15 Cons(A, Box<dyn FnOnce() -> LazyList<A>>),
17}
18impl<A: Clone> LazyList<A> {
19 pub fn nil() -> Self {
21 LazyList::Nil
22 }
23 pub fn cons(head: A, tail: impl FnOnce() -> LazyList<A> + 'static) -> Self {
25 LazyList::Cons(head, Box::new(tail))
26 }
27 pub fn take(self, n: usize) -> Vec<A> {
29 let mut result = Vec::with_capacity(n);
30 let mut current = self;
31 while result.len() < n {
32 match current {
33 LazyList::Nil => break,
34 LazyList::Cons(h, t) => {
35 result.push(h);
36 current = t();
37 }
38 }
39 }
40 result
41 }
42 pub fn is_nil(&self) -> bool {
44 matches!(self, LazyList::Nil)
45 }
46}
47#[allow(dead_code)]
52pub struct GuardedFix<A> {
53 cell: OnceCell<A>,
54}
55#[allow(dead_code)]
56impl<A: Clone + 'static> GuardedFix<A> {
57 pub fn evaluate(step: impl Fn(Box<dyn Fn() -> A>) -> A) -> A {
61 let placeholder: std::cell::RefCell<Option<A>> = std::cell::RefCell::new(None);
62 let result = step(Box::new(move || {
63 placeholder
64 .borrow()
65 .clone()
66 .expect("guarded: value not yet available")
67 }));
68 result
69 }
70 pub fn is_computed(&self) -> bool {
72 self.cell.get().is_some()
73 }
74}
75pub struct Memo<A> {
77 pub(super) lock: OnceLock<A>,
78 init: Arc<dyn Fn() -> A + Send + Sync>,
79}
80impl<A: Send + Sync + 'static> Memo<A> {
81 pub fn new(f: impl Fn() -> A + Send + Sync + 'static) -> Self {
83 Memo {
84 lock: OnceLock::new(),
85 init: Arc::new(f),
86 }
87 }
88 pub fn get(&self) -> &A {
90 self.lock.get_or_init(|| (self.init)())
91 }
92 pub fn is_initialized(&self) -> bool {
94 self.lock.get().is_some()
95 }
96}
97pub struct LazyBatch<A> {
102 items: Vec<Deferred<A>>,
103}
104impl<A: 'static> LazyBatch<A> {
105 pub fn new() -> Self {
107 Self { items: Vec::new() }
108 }
109 pub fn push(mut self, item: Deferred<A>) -> Self {
111 self.items.push(item);
112 self
113 }
114 pub fn force_all(self) -> Vec<A> {
116 self.items.into_iter().map(|d| d.force()).collect()
117 }
118 pub fn len(&self) -> usize {
120 self.items.len()
121 }
122 pub fn is_empty(&self) -> bool {
124 self.items.is_empty()
125 }
126}
127pub struct MemoFn<A> {
130 cell: OnceCell<A>,
131 func: Box<dyn Fn() -> A>,
132}
133impl<A> MemoFn<A> {
134 pub fn new(f: impl Fn() -> A + 'static) -> Self {
136 MemoFn {
137 cell: OnceCell::new(),
138 func: Box::new(f),
139 }
140 }
141 pub fn get(&self) -> &A {
143 self.cell.get_or_init(|| (self.func)())
144 }
145 pub fn is_cached(&self) -> bool {
147 self.cell.get().is_some()
148 }
149}
150pub struct Deferred<A> {
152 inner: Box<dyn FnOnce() -> A>,
153}
154impl<A: 'static> Deferred<A> {
155 pub fn new(f: impl FnOnce() -> A + 'static) -> Self {
157 Deferred { inner: Box::new(f) }
158 }
159 pub fn pure(a: A) -> Self {
161 Deferred::new(move || a)
162 }
163 pub fn force(self) -> A {
165 (self.inner)()
166 }
167 pub fn map<B: 'static>(self, f: impl FnOnce(A) -> B + 'static) -> Deferred<B> {
169 Deferred::new(move || f(self.force()))
170 }
171 pub fn bind<B: 'static>(self, f: impl FnOnce(A) -> Deferred<B> + 'static) -> Deferred<B> {
173 Deferred::new(move || f(self.force()).force())
174 }
175 pub fn zip<B: 'static>(self, other: Deferred<B>) -> Deferred<(A, B)> {
177 Deferred::new(move || (self.force(), other.force()))
178 }
179}
180#[allow(dead_code)]
184pub struct LazyStateMachineRs<S, I> {
185 state: Deferred<S>,
187 transition: Arc<dyn Fn(S, I) -> S + Send + Sync>,
189}
190#[allow(dead_code)]
191impl<S: Clone + 'static, I: 'static> LazyStateMachineRs<S, I> {
192 pub fn new(initial: S, transition: impl Fn(S, I) -> S + Send + Sync + 'static) -> Self {
194 Self {
195 state: Deferred::pure(initial),
196 transition: Arc::new(transition),
197 }
198 }
199 pub fn step(self, input: I) -> Self {
201 let t = self.transition.clone();
202 let t2 = t.clone();
203 let new_state = self.state.map(move |s| t(s, input));
204 Self {
205 state: new_state,
206 transition: t2,
207 }
208 }
209 pub fn current_state(self) -> S {
211 self.state.force()
212 }
213}
214#[allow(dead_code)]
218pub struct LazyWindowRs<T> {
219 buf: std::collections::VecDeque<Deferred<T>>,
220 capacity: usize,
221}
222#[allow(dead_code)]
223impl<T: 'static> LazyWindowRs<T> {
224 pub fn new(capacity: usize) -> Self {
226 Self {
227 buf: std::collections::VecDeque::with_capacity(capacity),
228 capacity,
229 }
230 }
231 pub fn push(&mut self, val: Deferred<T>) {
233 if self.buf.len() == self.capacity {
234 self.buf.pop_front();
235 }
236 self.buf.push_back(val);
237 }
238 pub fn force_all(self) -> Vec<T> {
240 self.buf.into_iter().map(|d| d.force()).collect()
241 }
242 pub fn len(&self) -> usize {
244 self.buf.len()
245 }
246 pub fn is_empty(&self) -> bool {
248 self.buf.is_empty()
249 }
250 pub fn capacity(&self) -> usize {
252 self.capacity
253 }
254}
255#[allow(dead_code)]
259#[derive(Debug, Clone, PartialEq, Eq)]
260pub enum CoNatRs {
261 Finite(u64),
263 Infinity,
265}
266#[allow(dead_code)]
267impl CoNatRs {
268 pub fn zero() -> Self {
270 CoNatRs::Finite(0)
271 }
272 pub fn succ(self) -> Self {
274 match self {
275 CoNatRs::Finite(n) => CoNatRs::Finite(n + 1),
276 CoNatRs::Infinity => CoNatRs::Infinity,
277 }
278 }
279 pub fn is_zero(&self) -> bool {
281 matches!(self, CoNatRs::Finite(0))
282 }
283 pub fn is_infinity(&self) -> bool {
285 matches!(self, CoNatRs::Infinity)
286 }
287 pub fn to_finite(self) -> Option<u64> {
289 match self {
290 CoNatRs::Finite(n) => Some(n),
291 CoNatRs::Infinity => None,
292 }
293 }
294 pub fn add(self, other: CoNatRs) -> CoNatRs {
296 match (self, other) {
297 (CoNatRs::Infinity, _) | (_, CoNatRs::Infinity) => CoNatRs::Infinity,
298 (CoNatRs::Finite(a), CoNatRs::Finite(b)) => CoNatRs::Finite(a + b),
299 }
300 }
301 pub fn min(self, other: CoNatRs) -> CoNatRs {
303 match (self, other) {
304 (CoNatRs::Finite(a), CoNatRs::Finite(b)) => CoNatRs::Finite(a.min(b)),
305 (CoNatRs::Infinity, x) | (x, CoNatRs::Infinity) => x,
306 }
307 }
308}
309pub enum LazyOption<A> {
311 None,
313 Some(Deferred<A>),
315}
316impl<A: 'static> LazyOption<A> {
317 pub fn none() -> Self {
319 LazyOption::None
320 }
321 pub fn some(f: impl FnOnce() -> A + 'static) -> Self {
323 LazyOption::Some(Deferred::new(f))
324 }
325 pub fn pure(a: A) -> Self {
327 LazyOption::Some(Deferred::pure(a))
328 }
329 pub fn is_none(&self) -> bool {
331 matches!(self, LazyOption::None)
332 }
333 pub fn force(self) -> Option<A> {
335 match self {
336 LazyOption::None => None,
337 LazyOption::Some(d) => Some(d.force()),
338 }
339 }
340 pub fn map<B: 'static>(self, f: impl FnOnce(A) -> B + 'static) -> LazyOption<B> {
342 match self {
343 LazyOption::None => LazyOption::None,
344 LazyOption::Some(d) => LazyOption::Some(d.map(f)),
345 }
346 }
347}
348#[allow(dead_code)]
352pub enum DelayRs<A> {
353 Now(A),
355 Later(Box<dyn FnOnce() -> DelayRs<A>>),
357}
358#[allow(dead_code)]
359impl<A: 'static> DelayRs<A> {
360 pub fn now(a: A) -> Self {
362 DelayRs::Now(a)
363 }
364 pub fn later(f: impl FnOnce() -> DelayRs<A> + 'static) -> Self {
366 DelayRs::Later(Box::new(f))
367 }
368 pub fn run(self, fuel: usize) -> Option<A> {
370 let mut current = self;
371 let mut remaining = fuel;
372 loop {
373 match current {
374 DelayRs::Now(a) => return Some(a),
375 DelayRs::Later(f) => {
376 if remaining == 0 {
377 return None;
378 }
379 remaining -= 1;
380 current = f();
381 }
382 }
383 }
384 }
385 pub fn map<B: 'static>(self, f: impl FnOnce(A) -> B + 'static) -> DelayRs<B> {
387 match self {
388 DelayRs::Now(a) => DelayRs::Now(f(a)),
389 DelayRs::Later(g) => DelayRs::later(move || g().map(f)),
390 }
391 }
392 pub fn bind<B: 'static>(self, f: impl FnOnce(A) -> DelayRs<B> + 'static) -> DelayRs<B> {
394 match self {
395 DelayRs::Now(a) => f(a),
396 DelayRs::Later(g) => DelayRs::later(move || g().bind(f)),
397 }
398 }
399}
400pub struct LazyPair<A, B> {
402 first: Deferred<A>,
403 second: Deferred<B>,
404}
405impl<A: 'static, B: 'static> LazyPair<A, B> {
406 pub fn new(a: Deferred<A>, b: Deferred<B>) -> Self {
408 Self {
409 first: a,
410 second: b,
411 }
412 }
413 pub fn force(self) -> (A, B) {
415 (self.first.force(), self.second.force())
416 }
417 pub fn map_first<C: 'static>(self, f: impl FnOnce(A) -> C + 'static) -> LazyPair<C, B> {
419 LazyPair {
420 first: self.first.map(f),
421 second: self.second,
422 }
423 }
424 pub fn map_second<C: 'static>(self, f: impl FnOnce(B) -> C + 'static) -> LazyPair<A, C> {
426 LazyPair {
427 first: self.first,
428 second: self.second.map(f),
429 }
430 }
431}
432pub struct Thunk<A> {
434 pub(super) cell: OnceCell<A>,
435 init: Option<Box<dyn FnOnce() -> A>>,
436}
437impl<A> Thunk<A> {
438 pub fn new(f: impl FnOnce() -> A + 'static) -> Self {
440 Thunk {
441 cell: OnceCell::new(),
442 init: Some(Box::new(f)),
443 }
444 }
445 pub fn evaluated(a: A) -> Self {
447 let cell = OnceCell::new();
448 let _ = cell.set(a);
449 Thunk { cell, init: None }
450 }
451 pub fn force(&mut self) -> &A {
453 if self.cell.get().is_none() {
454 if let Some(f) = self.init.take() {
455 let _ = self.cell.set(f());
456 }
457 }
458 self.cell.get().expect("thunk init failed")
459 }
460 pub fn is_evaluated(&self) -> bool {
462 self.cell.get().is_some()
463 }
464}