1use crate::Fx;
2
3use super::State;
4
5impl<'f, V: Clone> Fx<'f, (), V> {
6 pub fn pure(value: V) -> Self {
7 Fx::immediate((), value)
8 }
9}
10
11impl<'f, S: Clone, V: Clone> Fx<'f, S, V> {
12 pub fn value(value: V) -> Self {
13 Fx::pending(|s: S| Fx::immediate(s, value))
14 }
15
16 pub fn func<F>(f: F) -> Self
17 where
18 F: FnOnce(S) -> V + Clone + 'f,
19 {
20 State::get().map(f)
21 }
22
23 pub fn map_m<U, F>(self, f: F) -> Fx<'f, S, U>
24 where
25 U: Clone,
26 F: FnOnce(V) -> Fx<'f, S, U> + Clone + 'f,
27 {
28 self.adapt(|s| s, |_s, s, v| f(v).contra_map(|_| s, |_s, s| s))
29 }
30
31 pub fn map<U, F>(self, f: F) -> Fx<'f, S, U>
32 where
33 U: Clone,
34 F: FnOnce(V) -> U + Clone + 'f,
35 {
36 self.map_m(|v| Fx::value(f(v)))
37 }
38
39 pub fn flat_map<R, U, F>(self, f: F) -> Fx<'f, (S, R), U>
40 where
41 U: Clone,
42 V: Clone,
43 R: Clone,
44 F: FnOnce(V) -> Fx<'f, R, U> + Clone + 'f,
45 {
46 self.adapt(
47 |(s, _r)| s,
48 |_sr, s, v| {
49 f(v).adapt(
50 |(_s, r)| r,
51 |_sr, r, u| Fx::value(u).contra_map(|_sr| (s, r), |_sr, sr| sr),
52 )
53 },
54 )
55 }
56
57 pub fn then<U>(self, e: Fx<'f, S, U>) -> Fx<'f, S, U>
58 where
59 U: Clone,
60 {
61 self.map_m(|_| e)
62 }
63
64 pub fn and_then<T, U>(self, e: Fx<'f, T, U>) -> Fx<'f, (S, T), U>
65 where
66 T: Clone,
67 U: Clone,
68 {
69 self.flat_map(|_| e)
70 }
71
72 pub fn contra_map<Outer, Getter, Setter>(
73 self,
74 getter: Getter,
75 setter: Setter,
76 ) -> Fx<'f, Outer, V>
77 where
78 Outer: Clone,
79 Getter: FnOnce(Outer) -> S + Clone + 'f,
80 Setter: FnOnce(Outer, S) -> Outer + Clone + 'f,
81 {
82 self.adapt(
83 |t: Outer| getter(t),
84 |t, s, v| Fx::immediate(setter(t, s), v),
85 )
86 }
87}