1#[fp_macros::document_module]
39pub(crate) mod inner {
40 use {
41 crate::{
42 classes::{
43 RefSemimonad,
44 Semimonad,
45 },
46 dispatch::{
47 Ref,
48 Val,
49 },
50 kinds::*,
51 },
52 fp_macros::*,
53 };
54
55 #[document_type_parameters(
63 "The lifetime of the values.",
64 "The brand of the monad.",
65 "The type of the value inside the monad.",
66 "The type of the result.",
67 "The container type (owned or borrowed), inferred from the argument.",
68 "Dispatch marker type, inferred automatically."
69 )]
70 #[document_parameters("The closure implementing this dispatch.")]
71 pub trait BindDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, FA, Marker> {
72 #[document_signature]
74 #[document_parameters("The monadic value.")]
75 #[document_returns("The result of binding.")]
76 #[document_examples]
77 fn dispatch(
87 self,
88 ma: FA,
89 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>);
90 }
91
92 #[document_type_parameters(
94 "The lifetime.",
95 "The brand.",
96 "The input type.",
97 "The output type.",
98 "The closure type."
99 )]
100 #[document_parameters("The closure that takes owned values.")]
101 impl<'a, Brand, A, B, F>
102 BindDispatch<
103 'a,
104 Brand,
105 A,
106 B,
107 Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
108 Val,
109 > for F
110 where
111 Brand: Semimonad,
112 A: 'a,
113 B: 'a,
114 F: Fn(A) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
115 {
116 #[document_signature]
117 #[document_parameters("The monadic value.")]
118 #[document_returns("The result of binding.")]
119 #[document_examples]
120 fn dispatch(
130 self,
131 ma: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
132 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
133 Brand::bind(ma, self)
134 }
135 }
136
137 #[document_type_parameters(
141 "The lifetime.",
142 "The borrow lifetime.",
143 "The brand.",
144 "The input type.",
145 "The output type.",
146 "The closure type."
147 )]
148 #[document_parameters("The closure that takes references.")]
149 impl<'a, 'b, Brand, A, B, F>
150 BindDispatch<
151 'a,
152 Brand,
153 A,
154 B,
155 &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
156 Ref,
157 > for F
158 where
159 Brand: RefSemimonad,
160 A: 'a,
161 B: 'a,
162 F: Fn(&A) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
163 {
164 #[document_signature]
165 #[document_parameters("A reference to the monadic value.")]
166 #[document_returns("The result of binding.")]
167 #[document_examples]
168 fn dispatch(
185 self,
186 ma: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
187 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
188 Brand::ref_bind(ma, self)
189 }
190 }
191
192 #[document_type_parameters(
199 "The lifetime of the values.",
200 "The higher-kinded type brand.",
201 "The input type.",
202 "The intermediate type.",
203 "The output type.",
204 "Marker type (`Val` or `Ref`), inferred from the closures."
205 )]
206 #[document_parameters("The closure pair implementing this dispatch.")]
207 pub trait ComposeKleisliDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, C: 'a, Marker>
208 {
209 #[document_signature]
211 #[document_parameters("The input value.")]
212 #[document_returns("The result of composing f then g applied to the input.")]
213 #[document_examples]
214 fn dispatch(
225 self,
226 a: A,
227 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>);
228 }
229
230 #[document_type_parameters(
231 "The lifetime of the values.",
232 "The higher-kinded type brand.",
233 "The input type.",
234 "The intermediate type.",
235 "The output type.",
236 "The first closure type.",
237 "The second closure type."
238 )]
239 #[document_parameters("The closure pair.")]
240 impl<'a, Brand, A, B, C, F, G> ComposeKleisliDispatch<'a, Brand, A, B, C, Val> for (F, G)
241 where
242 Brand: Semimonad,
243 A: 'a,
244 B: 'a,
245 C: 'a,
246 F: Fn(A) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
247 G: Fn(B) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
248 {
249 #[document_signature]
250 #[document_parameters("The input value.")]
251 #[document_returns("The composed result.")]
252 #[document_examples]
253 fn dispatch(
264 self,
265 a: A,
266 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
267 Brand::bind(self.0(a), self.1)
268 }
269 }
270
271 #[document_type_parameters(
272 "The lifetime of the values.",
273 "The higher-kinded type brand.",
274 "The input type.",
275 "The intermediate type.",
276 "The output type.",
277 "The first closure type.",
278 "The second closure type."
279 )]
280 #[document_parameters("The closure pair.")]
281 impl<'a, Brand, A, B, C, F, G> ComposeKleisliDispatch<'a, Brand, A, B, C, Ref> for (F, G)
282 where
283 Brand: RefSemimonad,
284 A: 'a,
285 B: 'a,
286 C: 'a,
287 F: Fn(&A) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
288 G: Fn(&B) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
289 {
290 #[document_signature]
291 #[document_parameters("The input value.")]
292 #[document_returns("The composed result.")]
293 #[document_examples]
294 fn dispatch(
317 self,
318 a: A,
319 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
320 Brand::ref_bind(&(self.0(&a)), self.1)
321 }
322 }
323
324 #[document_signature]
329 #[document_type_parameters(
331 "The lifetime of the values.",
332 "The higher-kinded type brand.",
333 "The input type.",
334 "The intermediate type.",
335 "The output type.",
336 "Marker type, inferred from the closures."
337 )]
338 #[document_parameters("A tuple of (first arrow, second arrow).", "The input value.")]
340 #[document_returns("The result of applying f then g.")]
342 #[document_examples]
343 pub fn compose_kleisli<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, C: 'a, Marker>(
355 fg: impl ComposeKleisliDispatch<'a, Brand, A, B, C, Marker>,
356 a: A,
357 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
358 fg.dispatch(a)
359 }
360
361 #[document_signature]
368 #[document_type_parameters(
370 "The lifetime of the values.",
371 "The higher-kinded type brand.",
372 "The input type.",
373 "The intermediate type.",
374 "The output type.",
375 "The second arrow type (`B -> Of<C>`).",
376 "The first arrow type (`A -> Of<B>`).",
377 "Marker type, inferred from the closures."
378 )]
379 #[document_parameters("A tuple of (second arrow, first arrow).", "The input value.")]
381 #[document_returns("The result of applying g then f.")]
383 #[document_examples]
384 pub fn compose_kleisli_flipped<
398 'a,
399 Brand: Kind_cdc7cd43dac7585f,
400 A: 'a,
401 B: 'a,
402 C: 'a,
403 F,
404 G,
405 Marker,
406 >(
407 gf: (F, G),
408 a: A,
409 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
410 where
411 (G, F): ComposeKleisliDispatch<'a, Brand, A, B, C, Marker>, {
412 ComposeKleisliDispatch::dispatch((gf.1, gf.0), a)
413 }
414
415 #[document_type_parameters(
423 "The lifetime of the values.",
424 "The brand of the monad.",
425 "The type of the value(s) inside the inner layer.",
426 "Dispatch marker type, inferred automatically. Either [`Val`](crate::dispatch::Val) or [`Ref`](crate::dispatch::Ref)."
427 )]
428 #[document_parameters("The container implementing this dispatch.")]
429 pub trait JoinDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, Marker> {
430 #[document_signature]
432 #[document_returns("A container with one layer of nesting removed.")]
434 #[document_examples]
435 fn dispatch(self) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>);
446 }
447
448 #[document_type_parameters("The lifetime.", "The brand.", "The inner element type.")]
452 #[document_parameters("The nested monadic value.")]
453 impl<'a, Brand, A> JoinDispatch<'a, Brand, A, Val> for Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
454 where
455 Brand: Semimonad,
456 A: 'a,
457 {
458 #[document_signature]
459 #[document_returns("A container with one layer of nesting removed.")]
461 #[document_examples]
462 fn dispatch(self) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
473 Brand::bind(self, |ma| ma)
474 }
475 }
476
477 #[document_type_parameters("The lifetime.", "The brand.", "The inner element type.")]
481 #[document_parameters("A reference to the nested monadic value.")]
482 impl<'a, Brand, A> JoinDispatch<'a, Brand, A, Ref> for &Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
483 where
484 Brand: RefSemimonad,
485 A: 'a,
486 Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
487 {
488 #[document_signature]
489 #[document_returns("A container with one layer of nesting removed.")]
491 #[document_examples]
492 fn dispatch(self) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
504 Brand::ref_bind(self, |ma| ma.clone())
505 }
506 }
507
508 #[document_signature]
517 #[document_type_parameters(
519 "The lifetime of the values.",
520 "The container type (owned or borrowed). Brand is inferred from this.",
521 "The type of the value inside the monad.",
522 "The type of the result.",
523 "The brand, inferred via InferableBrand from FA and the closure's input type."
524 )]
525 #[document_parameters(
527 "The monadic value (owned for Val, borrowed for Ref).",
528 "The function to apply to the value."
529 )]
530 #[document_returns("The result of sequencing the computation.")]
532 #[document_examples]
533 pub fn bind<'a, FA, A: 'a, B: 'a, Brand>(
541 ma: FA,
542 f: impl BindDispatch<
543 'a,
544 Brand,
545 A,
546 B,
547 FA,
548 <FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
549 >,
550 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
551 where
552 Brand: Kind_cdc7cd43dac7585f,
553 FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
554 f.dispatch(ma)
555 }
556
557 #[document_signature]
565 #[document_type_parameters(
567 "The lifetime of the values.",
568 "The container type (owned or borrowed). Brand is inferred from this.",
569 "The input element type.",
570 "The output element type.",
571 "The brand, inferred via InferableBrand from FA and the closure's input type."
572 )]
573 #[document_parameters(
575 "The function to apply to each element.",
576 "The monadic value (owned for Val, borrowed for Ref)."
577 )]
578 #[document_returns("The result of binding the function over the value.")]
580 #[document_examples]
581 pub fn bind_flipped<'a, FA, A: 'a, B: 'a, Brand>(
589 f: impl BindDispatch<
590 'a,
591 Brand,
592 A,
593 B,
594 FA,
595 <FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, A>>::Marker,
596 >,
597 ma: FA,
598 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
599 where
600 Brand: Kind_cdc7cd43dac7585f,
601 FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, A>, {
602 f.dispatch(ma)
603 }
604
605 #[document_signature]
612 #[document_type_parameters(
614 "The lifetime of the values.",
615 "The container type (owned or borrowed). Brand is inferred from this.",
616 "The type of the value(s) inside the inner layer.",
617 "The brand, inferred via InferableBrand from FA.",
618 "The inner container type (e.g., `Option<i32>` for `Option<Option<i32>>`), inferred automatically."
619 )]
620 #[document_parameters("The nested monadic value (owned or borrowed).")]
622 #[document_returns("A container with one layer of nesting removed.")]
624 #[document_examples]
625 pub fn join<'a, FA, A: 'a, Brand, MidA: 'a>(
635 mma: FA
636 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
637 where
638 Brand: Kind_cdc7cd43dac7585f,
639 FA: InferableBrand_cdc7cd43dac7585f<'a, Brand, MidA>
640 + JoinDispatch<
641 'a,
642 Brand,
643 A,
644 <FA as InferableBrand_cdc7cd43dac7585f<'a, Brand, MidA>>::Marker,
645 >, {
646 mma.dispatch()
647 }
648
649 pub mod explicit {
656 use super::*;
657
658 #[document_signature]
668 #[document_type_parameters(
670 "The lifetime of the values.",
671 "The brand of the monad.",
672 "The type of the value inside the monad.",
673 "The type of the result.",
674 "The container type (owned or borrowed), inferred from the argument.",
675 "Dispatch marker type, inferred automatically."
676 )]
677 #[document_parameters(
679 "The monadic value (owned for Val, borrowed for Ref).",
680 "The function to apply to the value."
681 )]
682 #[document_returns("The result of sequencing the computation.")]
684 #[document_examples]
685 pub fn bind<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, FA, Marker>(
695 ma: FA,
696 f: impl BindDispatch<'a, Brand, A, B, FA, Marker>,
697 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
698 f.dispatch(ma)
699 }
700
701 #[document_signature]
707 #[document_type_parameters(
709 "The lifetime of the values.",
710 "The higher-kinded type brand.",
711 "The input element type.",
712 "The output element type.",
713 "The container type (owned or borrowed), inferred from the argument.",
714 "Marker type, inferred from the closure."
715 )]
716 #[document_parameters(
718 "The function to apply to each element.",
719 "The monadic value to bind over (owned for Val, borrowed for Ref)."
720 )]
721 #[document_returns("The result of binding the function over the value.")]
723 #[document_examples]
724 pub fn bind_flipped<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, FA, Marker>(
736 f: impl BindDispatch<'a, Brand, A, B, FA, Marker>,
737 ma: FA,
738 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
739 f.dispatch(ma)
740 }
741
742 #[document_signature]
754 #[document_type_parameters(
756 "The lifetime of the values.",
757 "The brand of the monad.",
758 "The type of the value(s) inside the inner layer.",
759 "Dispatch marker type, inferred automatically."
760 )]
761 #[document_parameters("The nested monadic value (owned or borrowed).")]
763 #[document_returns("A container with one layer of nesting removed.")]
765 #[document_examples]
767 pub fn join<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, Marker>(
784 mma: impl JoinDispatch<'a, Brand, A, Marker>
785 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
786 mma.dispatch()
787 }
788 }
789}
790
791pub use inner::*;