1#[fp_macros::document_module]
12mod inner {
13 use {
14 crate::{
15 Apply,
16 brands::{
17 VecBrand,
18 optics::*,
19 },
20 classes::{
21 ApplyFirst,
22 ApplySecond,
23 CloneableFn,
24 Functor,
25 Lift,
26 Pointed,
27 RefCountedPointer,
28 Semiapplicative,
29 Traversable,
30 optics::traversal::TraversalFunc,
31 profunctor::{
32 Choice,
33 Profunctor,
34 Strong,
35 Wander,
36 },
37 },
38 impl_kind,
39 kinds::*,
40 },
41 fp_macros::*,
42 };
43
44 type Ptr<FunctionBrand> = <FunctionBrand as CloneableFn>::PointerBrand;
46
47 #[document_type_parameters(
55 "The lifetime of the values.",
56 "The cloneable function brand.",
57 "The type of focus values extracted from the source.",
58 "The type of replacement values used during reconstruction.",
59 "The result type after reconstruction."
60 )]
61 pub struct BazaarList<'a, FunctionBrand: CloneableFn, A: 'a, B: 'a, T: 'a> {
62 pub foci: Vec<A>,
64 pub rebuild: <FunctionBrand as CloneableFn>::Of<'a, Vec<B>, T>,
66 }
67
68 impl_kind! {
69 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> for BazaarListBrand<FunctionBrand, A, B> {
70 type Of<'a, T: 'a>: 'a = BazaarList<'a, FunctionBrand, A, B, T>;
71 }
72 }
73
74 #[document_type_parameters(
75 "The cloneable function brand.",
76 "The focus type.",
77 "The replacement type."
78 )]
79 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Functor
80 for BazaarListBrand<FunctionBrand, A, B>
81 {
82 #[document_signature]
84 #[document_type_parameters(
86 "The lifetime of the values.",
87 "The original result type.",
88 "The new result type."
89 )]
90 #[document_parameters("The function to apply.", "The bazaar list to map over.")]
92 #[document_returns("A new `BazaarList` with the same foci but a transformed rebuild.")]
94 #[document_examples]
96 fn map<'a, T: 'a, U: 'a>(
115 func: impl Fn(T) -> U + 'a,
116 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, T>),
117 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, U>) {
118 let rebuild = fa.rebuild;
119 BazaarList {
120 foci: fa.foci,
121 rebuild: <FunctionBrand as CloneableFn>::new(move |bs: Vec<B>| {
122 func((*rebuild)(bs))
123 }),
124 }
125 }
126 }
127
128 #[document_type_parameters(
129 "The cloneable function brand.",
130 "The focus type.",
131 "The replacement type."
132 )]
133 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Pointed
134 for BazaarListBrand<FunctionBrand, A, B>
135 {
136 #[document_signature]
138 #[document_type_parameters("The lifetime of the value.", "The type of the value.")]
140 #[document_parameters("The value to wrap.")]
142 #[document_returns("A `BazaarList` with empty foci that ignores its input.")]
144 #[document_examples]
146 fn pure<'a, T: 'a>(a: T) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, T>) {
161 let a = Ptr::<FunctionBrand>::take_cell_new(a);
162 BazaarList {
163 foci: vec![],
164 rebuild: <FunctionBrand as CloneableFn>::new(move |_: Vec<B>| {
165 #[allow(clippy::expect_used)]
167 Ptr::<FunctionBrand>::take_cell_take(&a)
168 .expect("BazaarList::pure rebuild called more than once")
169 }),
170 }
171 }
172 }
173
174 #[document_type_parameters(
175 "The cloneable function brand.",
176 "The focus type.",
177 "The replacement type."
178 )]
179 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Lift
180 for BazaarListBrand<FunctionBrand, A, B>
181 {
182 #[document_signature]
187 #[document_type_parameters(
189 "The lifetime of the values.",
190 "The result type of the first `BazaarList`.",
191 "The result type of the second `BazaarList`.",
192 "The combined result type."
193 )]
194 #[document_parameters(
196 "The binary function to combine results.",
197 "The first `BazaarList`.",
198 "The second `BazaarList`."
199 )]
200 #[document_returns(
202 "A `BazaarList` with concatenated foci whose rebuild splits and delegates."
203 )]
204 #[document_examples]
206 fn lift2<'a, T, U, V>(
230 func: impl Fn(T, U) -> V + 'a,
231 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, T>),
232 fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, U>),
233 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, V>)
234 where
235 T: Clone + 'a,
236 U: Clone + 'a,
237 V: 'a, {
238 let split_at = fa.foci.len();
239 let mut foci = fa.foci;
240 foci.extend(fb.foci);
241 let rebuild_a = fa.rebuild;
242 let rebuild_b = fb.rebuild;
243 BazaarList {
244 foci,
245 rebuild: <FunctionBrand as CloneableFn>::new(move |mut bs: Vec<B>| {
246 let right = bs.split_off(split_at);
247 func((*rebuild_a)(bs), (*rebuild_b)(right))
248 }),
249 }
250 }
251 }
252
253 #[document_type_parameters(
254 "The cloneable function brand.",
255 "The focus type.",
256 "The replacement type."
257 )]
258 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Semiapplicative
259 for BazaarListBrand<FunctionBrand, A, B>
260 {
261 #[document_signature]
263 #[document_type_parameters(
265 "The lifetime of the values.",
266 "The brand of the cloneable function wrapper.",
267 "The input type.",
268 "The output type."
269 )]
270 #[document_parameters(
272 "The `BazaarList` containing the function.",
273 "The `BazaarList` containing the value."
274 )]
275 #[document_returns("A `BazaarList` with the function applied.")]
277 #[document_examples]
279 fn apply<'a, FnB: 'a + CloneableFn, T: 'a + Clone, U: 'a>(
304 ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnB as CloneableFn>::Of<'a, T, U>>),
305 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, T>),
306 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, U>) {
307 let split_at = ff.foci.len();
308 let mut foci = ff.foci;
309 foci.extend(fa.foci);
310 let rebuild_f = ff.rebuild;
311 let rebuild_a = fa.rebuild;
312 BazaarList {
313 foci,
314 rebuild: <FunctionBrand as CloneableFn>::new(move |mut bs: Vec<B>| {
315 let right = bs.split_off(split_at);
316 (*rebuild_f)(bs)((*rebuild_a)(right))
317 }),
318 }
319 }
320 }
321
322 #[document_type_parameters(
323 "The cloneable function brand.",
324 "The focus type.",
325 "The replacement type."
326 )]
327 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> ApplyFirst
328 for BazaarListBrand<FunctionBrand, A, B>
329 {
330 }
331 #[document_type_parameters(
332 "The cloneable function brand.",
333 "The focus type.",
334 "The replacement type."
335 )]
336 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> ApplySecond
337 for BazaarListBrand<FunctionBrand, A, B>
338 {
339 }
340
341 #[document_type_parameters(
352 "The lifetime of the values.",
353 "The cloneable function brand.",
354 "The type of focus values extracted from the source.",
355 "The type of replacement values used during reconstruction.",
356 "The source type.",
357 "The target type."
358 )]
359 pub struct Bazaar<'a, FunctionBrand: CloneableFn + 'a, A: 'a, B: 'a, S: 'a, T: 'a> {
360 pub run: <FunctionBrand as CloneableFn>::Of<'a, S, BazaarList<'a, FunctionBrand, A, B, T>>,
362 }
363
364 #[document_type_parameters(
365 "The lifetime of the values.",
366 "The cloneable function brand.",
367 "The type of focus values extracted from the source.",
368 "The type of replacement values used during reconstruction.",
369 "The source type.",
370 "The target type."
371 )]
372 impl<'a, FunctionBrand: CloneableFn, A: 'a, B: 'a, S: 'a, T: 'a>
373 Bazaar<'a, FunctionBrand, A, B, S, T>
374 {
375 #[document_signature]
377 #[document_parameters("The decomposition function from source to `BazaarList`.")]
379 #[document_returns("A new instance of the type.")]
381 #[document_examples]
383 pub fn new(
405 run: <FunctionBrand as CloneableFn>::Of<'a, S, BazaarList<'a, FunctionBrand, A, B, T>>
406 ) -> Self {
407 Bazaar {
408 run,
409 }
410 }
411 }
412
413 #[document_signature]
418 #[document_type_parameters(
420 "The lifetime of the values.",
421 "The cloneable function brand.",
422 "The type of focus values.",
423 "The type of replacement values.",
424 "The source type.",
425 "The target type.",
426 "The applicative context."
427 )]
428 #[document_parameters(
430 "The handler function that lifts each focus into the applicative.",
431 "The source value.",
432 "The bazaar to interpret."
433 )]
434 #[document_returns("The target wrapped in the applicative context.")]
436 #[document_examples]
438 pub fn run_bazaar<'a, FunctionBrand, A, B, S, T, F>(
469 handler: impl Fn(A) -> Apply!(<F as Kind!( type Of<'b, U: 'b>: 'b; )>::Of<'a, B>) + 'a,
470 s: S,
471 bazaar: &Bazaar<'a, FunctionBrand, A, B, S, T>,
472 ) -> Apply!(<F as Kind!( type Of<'b, U: 'b>: 'b; )>::Of<'a, T>)
473 where
474 FunctionBrand: CloneableFn + 'static,
475 A: 'a + Clone,
476 B: 'a + Clone,
477 S: 'a,
478 T: 'a,
479 F: crate::classes::Applicative,
480 Apply!(<F as Kind!( type Of<'b, U: 'b>: 'b; )>::Of<'a, B>): Clone,
481 Apply!(<F as Kind!( type Of<'b, U: 'b>: 'b; )>::Of<'a, Vec<B>>): Clone,
482 Apply!(<F as Kind!( type Of<'b, U: 'b>: 'b; )>::Of<'a, T>): Clone, {
483 let bl = (bazaar.run)(s);
484 let f_bs: Vec<Apply!(<F as Kind!( type Of<'b, U: 'b>: 'b; )>::Of<'a, B>)> =
485 bl.foci.into_iter().map(&handler).collect();
486 let f_vec_b: Apply!(<F as Kind!( type Of<'b, U: 'b>: 'b; )>::Of<'a, Vec<B>>) =
487 VecBrand::sequence::<'a, _, F>(f_bs);
488 let rebuild = bl.rebuild;
489 F::map(move |bs| (*rebuild)(bs), f_vec_b)
490 }
491
492 impl_kind! {
495 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> for BazaarBrand<FunctionBrand, A, B> {
496 #[document_default]
497 type Of<'a, S: 'a, T: 'a>: 'a = Bazaar<'a, FunctionBrand, A, B, S, T>;
498 }
499 }
500
501 #[document_type_parameters(
502 "The cloneable function brand.",
503 "The focus type.",
504 "The replacement type."
505 )]
506 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Profunctor
507 for BazaarBrand<FunctionBrand, A, B>
508 {
509 #[document_signature]
513 #[document_type_parameters(
515 "The lifetime of the values.",
516 "The new source type.",
517 "The original source type.",
518 "The original target type.",
519 "The new target type."
520 )]
521 #[document_parameters(
523 "The contravariant function to apply to the source.",
524 "The covariant function to apply to the target.",
525 "The bazaar instance to transform."
526 )]
527 #[document_returns("A transformed `Bazaar` instance.")]
529 #[document_examples]
531 fn dimap<'a, S: 'a, T: 'a, U: 'a, V: 'a>(
559 st: impl Fn(S) -> T + 'a,
560 uv: impl Fn(U) -> V + 'a,
561 puv: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, T, U>),
562 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, V>) {
563 let run = puv.run;
564 let uv = <FunctionBrand as CloneableFn>::new(uv);
565 Bazaar::new(<FunctionBrand as CloneableFn>::new(move |s: S| {
566 let bl = (*run)(st(s));
567 let rebuild = bl.rebuild;
568 let uv = uv.clone();
569 BazaarList {
570 foci: bl.foci,
571 rebuild: <FunctionBrand as CloneableFn>::new(move |bs: Vec<B>| {
572 (*uv)((*rebuild)(bs))
573 }),
574 }
575 }))
576 }
577 }
578
579 #[document_type_parameters(
580 "The cloneable function brand.",
581 "The focus type.",
582 "The replacement type."
583 )]
584 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Strong
585 for BazaarBrand<FunctionBrand, A, B>
586 {
587 #[document_signature]
591 #[document_type_parameters(
593 "The lifetime of the values.",
594 "The source type.",
595 "The target type.",
596 "The type of the second component."
597 )]
598 #[document_parameters("The bazaar instance to lift.")]
600 #[document_returns("A `Bazaar` that operates on pairs.")]
602 #[document_examples]
604 fn first<'a, S: 'a, T: 'a, C: 'a>(
628 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
629 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, (S, C), (T, C)>) {
630 let run = pab.run;
631 Bazaar::new(<FunctionBrand as CloneableFn>::new(move |(s, c): (S, C)| {
632 let bl = (*run)(s);
633 let rebuild = bl.rebuild;
634 let c = Ptr::<FunctionBrand>::take_cell_new(c);
635 BazaarList {
636 foci: bl.foci,
637 rebuild: <FunctionBrand as CloneableFn>::new(move |bs: Vec<B>| {
638 #[allow(clippy::expect_used)]
640 let c = Ptr::<FunctionBrand>::take_cell_take(&c)
641 .expect("BazaarList rebuild called more than once");
642 ((*rebuild)(bs), c)
643 }),
644 }
645 }))
646 }
647
648 #[document_signature]
652 #[document_type_parameters(
654 "The lifetime of the values.",
655 "The source type.",
656 "The target type.",
657 "The type of the first component."
658 )]
659 #[document_parameters("The bazaar instance to lift.")]
661 #[document_returns("A `Bazaar` that operates on pairs.")]
663 #[document_examples]
665 fn second<'a, S: 'a, T: 'a, C: 'a>(
689 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
690 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, (C, S), (C, T)>) {
691 let run = pab.run;
692 Bazaar::new(<FunctionBrand as CloneableFn>::new(move |(c, s): (C, S)| {
693 let bl = (*run)(s);
694 let rebuild = bl.rebuild;
695 let c = Ptr::<FunctionBrand>::take_cell_new(c);
696 BazaarList {
697 foci: bl.foci,
698 rebuild: <FunctionBrand as CloneableFn>::new(move |bs: Vec<B>| {
699 #[allow(clippy::expect_used)]
701 let c = Ptr::<FunctionBrand>::take_cell_take(&c)
702 .expect("BazaarList rebuild called more than once");
703 (c, (*rebuild)(bs))
704 }),
705 }
706 }))
707 }
708 }
709
710 #[document_type_parameters(
711 "The cloneable function brand.",
712 "The focus type.",
713 "The replacement type."
714 )]
715 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Choice
716 for BazaarBrand<FunctionBrand, A, B>
717 {
718 #[document_signature]
722 #[document_type_parameters(
724 "The lifetime of the values.",
725 "The source type.",
726 "The target type.",
727 "The type of the `Ok` variant."
728 )]
729 #[document_parameters("The bazaar instance to lift.")]
731 #[document_returns("A `Bazaar` that operates on `Result` types.")]
733 #[document_examples]
735 fn left<'a, S: 'a, T: 'a, C: 'a>(
762 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
763 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, Result<C, S>, Result<C, T>>)
764 {
765 let run = pab.run;
766 Bazaar::new(<FunctionBrand as CloneableFn>::new(move |r: Result<C, S>| match r {
767 Err(s) => {
768 let bl = (*run)(s);
769 let rebuild = bl.rebuild;
770 BazaarList {
771 foci: bl.foci,
772 rebuild: <FunctionBrand as CloneableFn>::new(move |bs: Vec<B>| {
773 Err((*rebuild)(bs))
774 }),
775 }
776 }
777 Ok(c) => {
778 let c = Ptr::<FunctionBrand>::take_cell_new(c);
779 BazaarList {
780 foci: vec![],
781 rebuild: <FunctionBrand as CloneableFn>::new(move |_: Vec<B>| {
782 #[allow(clippy::expect_used)]
784 Ok(Ptr::<FunctionBrand>::take_cell_take(&c)
785 .expect("BazaarList rebuild called more than once"))
786 }),
787 }
788 }
789 }))
790 }
791
792 #[document_signature]
796 #[document_type_parameters(
798 "The lifetime of the values.",
799 "The source type.",
800 "The target type.",
801 "The type of the `Err` variant."
802 )]
803 #[document_parameters("The bazaar instance to lift.")]
805 #[document_returns("A `Bazaar` that operates on `Result` types.")]
807 #[document_examples]
809 fn right<'a, S: 'a, T: 'a, C: 'a>(
836 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
837 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, Result<S, C>, Result<T, C>>)
838 {
839 let run = pab.run;
840 Bazaar::new(<FunctionBrand as CloneableFn>::new(move |r: Result<S, C>| match r {
841 Ok(s) => {
842 let bl = (*run)(s);
843 let rebuild = bl.rebuild;
844 BazaarList {
845 foci: bl.foci,
846 rebuild: <FunctionBrand as CloneableFn>::new(move |bs: Vec<B>| {
847 Ok((*rebuild)(bs))
848 }),
849 }
850 }
851 Err(c) => {
852 let c = Ptr::<FunctionBrand>::take_cell_new(c);
853 BazaarList {
854 foci: vec![],
855 rebuild: <FunctionBrand as CloneableFn>::new(move |_: Vec<B>| {
856 #[allow(clippy::expect_used)]
858 Err(Ptr::<FunctionBrand>::take_cell_take(&c)
859 .expect("BazaarList rebuild called more than once"))
860 }),
861 }
862 }
863 }))
864 }
865 }
866
867 #[document_type_parameters(
868 "The cloneable function brand.",
869 "The focus type.",
870 "The replacement type."
871 )]
872 impl<FunctionBrand: CloneableFn + 'static, A: 'static + Clone, B: 'static + Clone> Wander
873 for BazaarBrand<FunctionBrand, A, B>
874 {
875 #[document_signature]
880 #[document_type_parameters(
882 "The lifetime of the values.",
883 "The outer source type.",
884 "The outer target type.",
885 "The inner source type (focus of the traversal).",
886 "The inner target type."
887 )]
888 #[document_parameters("The traversal function.", "The bazaar instance to compose with.")]
890 #[document_returns("A `Bazaar` that traverses the outer structure.")]
892 #[document_examples]
894 fn wander<'a, S: 'a, T: 'a, A2: 'a, B2: 'a + Clone>(
951 traversal: impl TraversalFunc<'a, S, T, A2, B2> + 'a,
952 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, A2, B2>),
953 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>) {
954 let run = pab.run;
955 Bazaar::new(<FunctionBrand as CloneableFn>::new(move |s: S| {
956 let run = run.clone();
957 traversal.apply::<BazaarListBrand<FunctionBrand, A, B>>(
958 Box::new(move |a2: A2| (*run)(a2)),
959 s,
960 )
961 }))
962 }
963 }
964}
965pub use inner::*;
966
967impl<'a, FB: crate::classes::cloneable_fn::CloneableFn + 'static, A: Clone + 'a, B: 'a, T: 'a> Clone
968 for BazaarList<'a, FB, A, B, T>
969where
970 <FB as crate::classes::cloneable_fn::CloneableFn>::Of<'a, Vec<B>, T>: Clone,
971{
972 fn clone(&self) -> Self {
973 BazaarList {
974 foci: self.foci.clone(),
975 rebuild: self.rebuild.clone(),
976 }
977 }
978}