1use crate::{
9 Applicative, Effect3, Effect4, Effect5, Functor, Monad, MonadEffect3, MonadEffect4,
10 MonadEffect5,
11};
12use crate::{HKT, HKT3, HKT4, HKT5, Placeholder};
13
14#[derive(Debug, PartialEq)]
21pub struct MyCustomEffectType<T, E, W> {
22 pub value: T,
23 pub error: Option<E>,
24 pub warnings: Vec<W>,
25}
26
27pub struct MyEffectHktWitness<E, W>(Placeholder, E, W);
32
33impl<E, W> HKT for MyEffectHktWitness<E, W> {
34 type Type<T> = MyCustomEffectType<T, E, W>;
35}
36
37impl<E, W> HKT3<E, W> for MyEffectHktWitness<E, W> {
38 type Type<T> = MyCustomEffectType<T, E, W>;
39}
40
41pub struct MyEffect;
47
48impl Effect3 for MyEffect {
49 type Fixed1 = String;
50 type Fixed2 = String;
51 type HktWitness = MyEffectHktWitness<Self::Fixed1, Self::Fixed2>;
52}
53
54impl Functor<MyEffectHktWitness<String, String>> for MyEffectHktWitness<String, String> {
55 fn fmap<A, B, Func>(
56 m_a: MyCustomEffectType<A, String, String>,
57 f: Func,
58 ) -> MyCustomEffectType<B, String, String>
59 where
60 Func: FnOnce(A) -> B,
61 {
62 MyCustomEffectType {
63 value: f(m_a.value),
64 error: m_a.error,
65 warnings: m_a.warnings,
66 }
67 }
68}
69
70impl Applicative<MyEffectHktWitness<String, String>> for MyEffectHktWitness<String, String> {
71 fn pure<T>(value: T) -> MyCustomEffectType<T, String, String> {
72 MyCustomEffectType {
73 value,
74 error: None,
75 warnings: Vec::new(),
76 }
77 }
78
79 fn apply<A, B, Func>(
80 mut f_ab: MyCustomEffectType<Func, String, String>,
81 f_a: MyCustomEffectType<A, String, String>,
82 ) -> MyCustomEffectType<B, String, String>
83 where
84 Func: FnMut(A) -> B,
85 {
86 if f_ab.error.is_some() {
87 return MyCustomEffectType {
88 value: (f_ab.value)(f_a.value), error: f_ab.error,
90 warnings: f_ab.warnings,
91 };
92 }
93 if f_a.error.is_some() {
94 return MyCustomEffectType {
95 value: (f_ab.value)(f_a.value), error: f_a.error,
97 warnings: f_a.warnings,
98 };
99 }
100
101 let mut combined_warnings = f_ab.warnings;
102 combined_warnings.extend(f_a.warnings);
103
104 MyCustomEffectType {
105 value: (f_ab.value)(f_a.value),
106 error: None,
107 warnings: combined_warnings,
108 }
109 }
110}
111
112impl Monad<MyEffectHktWitness<String, String>> for MyEffectHktWitness<String, String> {
113 fn bind<A, B, Func>(
114 m_a: MyCustomEffectType<A, String, String>,
115 f: Func,
116 ) -> MyCustomEffectType<B, String, String>
117 where
118 Func: FnOnce(A) -> MyCustomEffectType<B, String, String>,
119 {
120 if m_a.error.is_some() {
121 return MyCustomEffectType {
122 value: f(m_a.value).value,
123 error: m_a.error,
124 warnings: m_a.warnings,
125 };
126 }
127 let mut next_effect = f(m_a.value);
128 let mut combined_warnings = m_a.warnings;
129 combined_warnings.extend(next_effect.warnings);
130 next_effect.warnings = combined_warnings;
131 next_effect
132 }
133}
134
135pub struct MyMonadEffect3;
140
141impl MonadEffect3<MyEffect> for MyMonadEffect3 {
142 fn pure<T>(
143 value: T,
144 ) -> <<MyEffect as Effect3>::HktWitness as HKT3<
145 <MyEffect as Effect3>::Fixed1,
146 <MyEffect as Effect3>::Fixed2,
147 >>::Type<T> {
148 <MyEffect as Effect3>::HktWitness::pure(value)
149 }
150
151 fn bind<T, U, Func>(
152 effect: <<MyEffect as Effect3>::HktWitness as HKT3<
153 <MyEffect as Effect3>::Fixed1,
154 <MyEffect as Effect3>::Fixed2,
155 >>::Type<T>,
156 f: Func,
157 ) -> <<MyEffect as Effect3>::HktWitness as HKT3<
158 <MyEffect as Effect3>::Fixed1,
159 <MyEffect as Effect3>::Fixed2,
160 >>::Type<U>
161 where
162 Func: FnMut(
163 T,
164 ) -> <<MyEffect as Effect3>::HktWitness as HKT3<
165 <MyEffect as Effect3>::Fixed1,
166 <MyEffect as Effect3>::Fixed2,
167 >>::Type<U>,
168 {
169 <MyEffect as Effect3>::HktWitness::bind(effect, f)
170 }
171}
172
173pub trait LoggableEffect3<E: Effect3>: MonadEffect3<E>
178where
179 E::HktWitness: Functor<E::HktWitness> + Sized,
180{
181 fn log<T>(
192 effect: <E::HktWitness as HKT3<E::Fixed1, E::Fixed2>>::Type<T>,
193 log: E::Fixed2,
194 ) -> <E::HktWitness as HKT3<E::Fixed1, E::Fixed2>>::Type<T>;
195}
196
197impl LoggableEffect3<MyEffect> for MyMonadEffect3 {
198 fn log<T>(
199 mut effect: <<MyEffect as Effect3>::HktWitness as HKT3<
200 <MyEffect as Effect3>::Fixed1,
201 <MyEffect as Effect3>::Fixed2,
202 >>::Type<T>,
203 log: <MyEffect as Effect3>::Fixed2,
204 ) -> <<MyEffect as Effect3>::HktWitness as HKT3<
205 <MyEffect as Effect3>::Fixed1,
206 <MyEffect as Effect3>::Fixed2,
207 >>::Type<T> {
208 effect.warnings.push(log);
209 effect
210 }
211}
212
213#[derive(Debug, PartialEq)]
221pub struct MyCustomEffectType4<T, F1, F2, F3> {
222 pub value: T,
223 pub f1: Option<F1>,
224 pub f2: Vec<F2>,
225 pub f3: Vec<F3>,
226}
227
228pub struct MyEffectHktWitness4<F1, F2, F3>(Placeholder, F1, F2, F3);
232
233impl<F1, F2, F3> HKT for MyEffectHktWitness4<F1, F2, F3> {
234 type Type<T> = MyCustomEffectType4<T, F1, F2, F3>;
235}
236
237impl<F1, F2, F3> HKT4<F1, F2, F3> for MyEffectHktWitness4<F1, F2, F3> {
238 type Type<T> = MyCustomEffectType4<T, F1, F2, F3>;
239}
240
241pub struct MyEffect4;
247
248impl Effect4 for MyEffect4 {
249 type Fixed1 = String; type Fixed2 = String; type Fixed3 = u64; type HktWitness = MyEffectHktWitness4<Self::Fixed1, Self::Fixed2, Self::Fixed3>;
253}
254
255impl Functor<MyEffectHktWitness4<String, String, u64>>
256 for MyEffectHktWitness4<String, String, u64>
257{
258 fn fmap<A, B, Func>(
259 m_a: MyCustomEffectType4<A, String, String, u64>,
260 f: Func,
261 ) -> MyCustomEffectType4<B, String, String, u64>
262 where
263 Func: FnOnce(A) -> B,
264 {
265 MyCustomEffectType4 {
266 value: f(m_a.value),
267 f1: m_a.f1,
268 f2: m_a.f2,
269 f3: m_a.f3,
270 }
271 }
272}
273
274impl Applicative<MyEffectHktWitness4<String, String, u64>>
275 for MyEffectHktWitness4<String, String, u64>
276{
277 fn pure<T>(value: T) -> MyCustomEffectType4<T, String, String, u64> {
278 MyCustomEffectType4 {
279 value,
280 f1: None,
281 f2: Vec::new(),
282 f3: Vec::new(),
283 }
284 }
285
286 fn apply<A, B, Func>(
287 mut f_ab: MyCustomEffectType4<Func, String, String, u64>,
288 f_a: MyCustomEffectType4<A, String, String, u64>,
289 ) -> MyCustomEffectType4<B, String, String, u64>
290 where
291 Func: FnMut(A) -> B,
292 {
293 if f_ab.f1.is_some() {
294 return MyCustomEffectType4 {
295 value: (f_ab.value)(f_a.value), f1: f_ab.f1,
297 f2: f_ab.f2,
298 f3: f_ab.f3,
299 };
300 }
301 if f_a.f1.is_some() {
302 return MyCustomEffectType4 {
303 value: (f_ab.value)(f_a.value), f1: f_a.f1,
305 f2: f_a.f2,
306 f3: f_a.f3,
307 };
308 }
309
310 let mut combined_f2 = f_ab.f2;
311 combined_f2.extend(f_a.f2);
312
313 let mut combined_f3 = f_ab.f3;
314 combined_f3.extend(f_a.f3);
315
316 MyCustomEffectType4 {
317 value: (f_ab.value)(f_a.value),
318 f1: None,
319 f2: combined_f2,
320 f3: combined_f3,
321 }
322 }
323}
324
325impl Monad<MyEffectHktWitness4<String, String, u64>> for MyEffectHktWitness4<String, String, u64> {
326 fn bind<A, B, Func>(
327 m_a: MyCustomEffectType4<A, String, String, u64>,
328 f: Func,
329 ) -> MyCustomEffectType4<B, String, String, u64>
330 where
331 Func: FnOnce(A) -> MyCustomEffectType4<B, String, String, u64>,
332 {
333 if m_a.f1.is_some() {
334 return MyCustomEffectType4 {
335 value: f(m_a.value).value, f1: m_a.f1,
337 f2: m_a.f2,
338 f3: m_a.f3,
339 };
340 }
341 let mut next_effect = f(m_a.value);
342 let mut combined_f2 = m_a.f2;
343 combined_f2.extend(next_effect.f2);
344 next_effect.f2 = combined_f2;
345
346 let mut combined_f3 = m_a.f3;
347 combined_f3.extend(next_effect.f3);
348 next_effect.f3 = combined_f3;
349
350 next_effect
351 }
352}
353
354pub struct MyMonadEffect4;
359
360impl MonadEffect4<MyEffect4> for MyMonadEffect4 {
361 fn pure<T>(
362 value: T,
363 ) -> <<MyEffect4 as Effect4>::HktWitness as HKT4<
364 <MyEffect4 as Effect4>::Fixed1,
365 <MyEffect4 as Effect4>::Fixed2,
366 <MyEffect4 as Effect4>::Fixed3,
367 >>::Type<T> {
368 <MyEffect4 as Effect4>::HktWitness::pure(value)
369 }
370
371 fn bind<T, U, Func>(
372 effect: <<MyEffect4 as Effect4>::HktWitness as HKT4<
373 <MyEffect4 as Effect4>::Fixed1,
374 <MyEffect4 as Effect4>::Fixed2,
375 <MyEffect4 as Effect4>::Fixed3,
376 >>::Type<T>,
377 f: Func,
378 ) -> <<MyEffect4 as Effect4>::HktWitness as HKT4<
379 <MyEffect4 as Effect4>::Fixed1,
380 <MyEffect4 as Effect4>::Fixed2,
381 <MyEffect4 as Effect4>::Fixed3,
382 >>::Type<U>
383 where
384 Func: FnMut(
385 T,
386 ) -> <<MyEffect4 as Effect4>::HktWitness as HKT4<
387 <MyEffect4 as Effect4>::Fixed1,
388 <MyEffect4 as Effect4>::Fixed2,
389 <MyEffect4 as Effect4>::Fixed3,
390 >>::Type<U>,
391 {
392 <MyEffect4 as Effect4>::HktWitness::bind(effect, f)
393 }
394}
395
396pub trait LoggableEffect4<E: Effect4>: MonadEffect4<E>
401where
402 E::HktWitness: Functor<E::HktWitness> + Sized,
403{
404 fn log<T>(
415 effect: <E::HktWitness as HKT4<E::Fixed1, E::Fixed2, E::Fixed3>>::Type<T>,
416 log: E::Fixed3,
417 ) -> <E::HktWitness as HKT4<E::Fixed1, E::Fixed2, E::Fixed3>>::Type<T>;
418}
419
420impl LoggableEffect4<MyEffect4> for MyMonadEffect4 {
421 fn log<T>(
422 mut effect: <<MyEffect4 as Effect4>::HktWitness as HKT4<
423 <MyEffect4 as Effect4>::Fixed1,
424 <MyEffect4 as Effect4>::Fixed2,
425 <MyEffect4 as Effect4>::Fixed3,
426 >>::Type<T>,
427 log: <MyEffect4 as Effect4>::Fixed3,
428 ) -> <<MyEffect4 as Effect4>::HktWitness as HKT4<
429 <MyEffect4 as Effect4>::Fixed1,
430 <MyEffect4 as Effect4>::Fixed2,
431 <MyEffect4 as Effect4>::Fixed3,
432 >>::Type<T> {
433 effect.f3.push(log);
434 effect
435 }
436}
437
438#[derive(Debug, PartialEq)]
447pub struct MyCustomEffectType5<T, F1, F2, F3, F4> {
448 pub value: T,
449 pub f1: Option<F1>,
450 pub f2: Vec<F2>,
451 pub f3: Vec<F3>,
452 pub f4: Vec<F4>,
453}
454
455pub struct MyEffectHktWitness5<F1, F2, F3, F4>(Placeholder, F1, F2, F3, F4);
459
460impl<F1, F2, F3, F4> HKT for MyEffectHktWitness5<F1, F2, F3, F4> {
461 type Type<T> = MyCustomEffectType5<T, F1, F2, F3, F4>;
462}
463
464impl<F1, F2, F3, F4> HKT5<F1, F2, F3, F4> for MyEffectHktWitness5<F1, F2, F3, F4> {
465 type Type<T> = MyCustomEffectType5<T, F1, F2, F3, F4>;
466}
467
468pub struct MyEffect5;
474
475impl Effect5 for MyEffect5 {
476 type Fixed1 = String;
477 type Fixed2 = String;
478 type Fixed3 = u64;
479 type Fixed4 = String;
480 type HktWitness = MyEffectHktWitness5<Self::Fixed1, Self::Fixed2, Self::Fixed3, Self::Fixed4>;
481}
482
483impl Functor<MyEffectHktWitness5<String, String, u64, String>>
484 for MyEffectHktWitness5<String, String, u64, String>
485{
486 fn fmap<A, B, Func>(
487 m_a: MyCustomEffectType5<A, String, String, u64, String>,
488 f: Func,
489 ) -> MyCustomEffectType5<B, String, String, u64, String>
490 where
491 Func: FnOnce(A) -> B,
492 {
493 MyCustomEffectType5 {
494 value: f(m_a.value),
495 f1: m_a.f1,
496 f2: m_a.f2,
497 f3: m_a.f3,
498 f4: m_a.f4,
499 }
500 }
501}
502
503impl Applicative<MyEffectHktWitness5<String, String, u64, String>>
504 for MyEffectHktWitness5<String, String, u64, String>
505{
506 fn pure<T>(value: T) -> MyCustomEffectType5<T, String, String, u64, String> {
507 MyCustomEffectType5 {
508 value,
509 f1: None,
510 f2: Vec::new(),
511 f3: Vec::new(),
512 f4: Vec::new(),
513 }
514 }
515
516 fn apply<A, B, Func>(
517 mut f_ab: MyCustomEffectType5<Func, String, String, u64, String>,
518 f_a: MyCustomEffectType5<A, String, String, u64, String>,
519 ) -> MyCustomEffectType5<B, String, String, u64, String>
520 where
521 Func: FnMut(A) -> B,
522 {
523 if f_ab.f1.is_some() {
524 return MyCustomEffectType5 {
525 value: (f_ab.value)(f_a.value), f1: f_ab.f1,
527 f2: f_ab.f2,
528 f3: f_ab.f3,
529 f4: f_ab.f4,
530 };
531 }
532 if f_a.f1.is_some() {
533 return MyCustomEffectType5 {
534 value: (f_ab.value)(f_a.value), f1: f_a.f1,
536 f2: f_a.f2,
537 f3: f_a.f3,
538 f4: f_a.f4,
539 };
540 }
541
542 let mut combined_f2 = f_ab.f2;
543 combined_f2.extend(f_a.f2);
544
545 let mut combined_f3 = f_ab.f3;
546 combined_f3.extend(f_a.f3);
547
548 let mut combined_f4 = f_ab.f4;
549 combined_f4.extend(f_a.f4);
550
551 MyCustomEffectType5 {
552 value: (f_ab.value)(f_a.value),
553 f1: None,
554 f2: combined_f2,
555 f3: combined_f3,
556 f4: combined_f4,
557 }
558 }
559}
560
561impl Monad<MyEffectHktWitness5<String, String, u64, String>>
562 for MyEffectHktWitness5<String, String, u64, String>
563{
564 fn bind<A, B, Func>(
565 m_a: MyCustomEffectType5<A, String, String, u64, String>,
566 f: Func,
567 ) -> MyCustomEffectType5<B, String, String, u64, String>
568 where
569 Func: FnOnce(A) -> MyCustomEffectType5<B, String, String, u64, String>,
570 {
571 if m_a.f1.is_some() {
572 return MyCustomEffectType5 {
573 value: f(m_a.value).value, f1: m_a.f1,
575 f2: m_a.f2,
576 f3: m_a.f3,
577 f4: m_a.f4,
578 };
579 }
580 let mut next_effect = f(m_a.value);
581
582 let mut combined_f2 = m_a.f2;
583 combined_f2.extend(next_effect.f2);
584 next_effect.f2 = combined_f2;
585
586 let mut combined_f3 = m_a.f3;
587 combined_f3.extend(next_effect.f3);
588 next_effect.f3 = combined_f3;
589
590 let mut combined_f4 = m_a.f4;
591 combined_f4.extend(next_effect.f4);
592 next_effect.f4 = combined_f4;
593
594 next_effect
595 }
596}
597
598pub struct MyMonadEffect5;
603
604impl MonadEffect5<MyEffect5> for MyMonadEffect5 {
605 fn pure<T>(
606 value: T,
607 ) -> <<MyEffect5 as Effect5>::HktWitness as HKT5<
608 <MyEffect5 as Effect5>::Fixed1,
609 <MyEffect5 as Effect5>::Fixed2,
610 <MyEffect5 as Effect5>::Fixed3,
611 <MyEffect5 as Effect5>::Fixed4,
612 >>::Type<T> {
613 <MyEffect5 as Effect5>::HktWitness::pure(value)
614 }
615
616 fn bind<T, U, Func>(
617 effect: <<MyEffect5 as Effect5>::HktWitness as HKT5<
618 <MyEffect5 as Effect5>::Fixed1,
619 <MyEffect5 as Effect5>::Fixed2,
620 <MyEffect5 as Effect5>::Fixed3,
621 <MyEffect5 as Effect5>::Fixed4,
622 >>::Type<T>,
623 f: Func,
624 ) -> <<MyEffect5 as Effect5>::HktWitness as HKT5<
625 <MyEffect5 as Effect5>::Fixed1,
626 <MyEffect5 as Effect5>::Fixed2,
627 <MyEffect5 as Effect5>::Fixed3,
628 <MyEffect5 as Effect5>::Fixed4,
629 >>::Type<U>
630 where
631 Func: FnMut(
632 T,
633 ) -> <<MyEffect5 as Effect5>::HktWitness as HKT5<
634 <MyEffect5 as Effect5>::Fixed1,
635 <MyEffect5 as Effect5>::Fixed2,
636 <MyEffect5 as Effect5>::Fixed3,
637 <MyEffect5 as Effect5>::Fixed4,
638 >>::Type<U>,
639 {
640 <MyEffect5 as Effect5>::HktWitness::bind(effect, f)
641 }
642}
643
644pub trait LoggableEffect5<E: Effect5>: MonadEffect5<E>
649where
650 E::HktWitness: Functor<E::HktWitness> + Sized,
651{
652 #[allow(clippy::type_complexity)]
663 fn log<T>(
664 effect: <E::HktWitness as HKT5<E::Fixed1, E::Fixed2, E::Fixed3, E::Fixed4>>::Type<T>,
665 log: E::Fixed4,
666 ) -> <E::HktWitness as HKT5<E::Fixed1, E::Fixed2, E::Fixed3, E::Fixed4>>::Type<T>;
667}
668
669impl LoggableEffect5<MyEffect5> for MyMonadEffect5 {
670 #[allow(clippy::type_complexity)]
671 fn log<T>(
672 mut effect: <<MyEffect5 as Effect5>::HktWitness as HKT5<
673 <MyEffect5 as Effect5>::Fixed1,
674 <MyEffect5 as Effect5>::Fixed2,
675 <MyEffect5 as Effect5>::Fixed3,
676 <MyEffect5 as Effect5>::Fixed4,
677 >>::Type<T>,
678 log: <MyEffect5 as Effect5>::Fixed4,
679 ) -> <<MyEffect5 as Effect5>::HktWitness as HKT5<
680 <MyEffect5 as Effect5>::Fixed1,
681 <MyEffect5 as Effect5>::Fixed2,
682 <MyEffect5 as Effect5>::Fixed3,
683 <MyEffect5 as Effect5>::Fixed4,
684 >>::Type<T> {
685 effect.f4.push(log);
686 effect
687 }
688}