Need help implementing a trait function `traverse` for `Vec`

Hello. As a personal learning exercise, I've been trying to see how far I could get with implementing functional programming concepts (my project's page is at github(dot)com/nothingnesses/rust-fp-library/tree/wip-traversable , but the forum won't let me add more than 2 links), but I've hit a wall trying to implement a traverse function for Vec. Here's the condensed code for my current attempt.

My issue is that I think I need to add some trait bound(s) to the relevant function signatures on the trait and in the implementing instances:

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `F: Kind1<A>` is not satisfied
   --> src/lib.rs:717:7
    |
717 |                         Apply<F, (A,)>,
    |                         ^^^^^^^^^^^^^^ the trait `Kind1<A>` is not implemented for `F`
    |
note: required for `F` to implement `Kind<(A,)>`
   --> src/lib.rs:44:31
    |
44  |         impl<Brand, $($Generics),+> Kind<($($Generics,)+)> for Brand
    |                                     ^^^^^^^^^^^^^^^^^^^^^^     ^^^^^
45  |         where
46  |             Brand: $KindN<$($Generics),+>,
    |                    ---------------------- unsatisfied trait bound introduced here
...
210 | make_trait_kind!(Kind1, Apply1, "* -> *", (A));
    | ---------------------------------------------- in this macro invocation
    = note: this error originates in the macro `make_trait_kind` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `F` with trait `Kind1`
    |
696 |         F: 'a + Kind<(B,)> + Kind<(Apply<Self, (B,)>,)> + Applicative + Kind1<A>,
    |                                                                       ++++++++++

error[E0277]: the trait bound `F: Kind1<Arc<dyn Fn(<VecBrand as Kind<(A,)>>::Output) -> ...>>` is not satisfied
   --> src/lib.rs:718:7
    |
718 |                         Apply<F, (ClonableFn<'a, Apply<Self, (A,)>, Apply<Self, (A,)>>,)>,
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Kind1<Arc<(dyn Fn(<VecBrand as Kind<(A,)>>::Output) -> <VecBrand as Kind<(A,)>>::Output + 'a)>>` is not implemented for `F`
    |
note: required for `F` to implement `Kind<(Arc<(dyn Fn(<VecBrand as Kind<(A,)>>::Output) -> <VecBrand as Kind<(A,)>>::Output + 'a)>,)>`
   --> src/lib.rs:44:31
    |
44  |         impl<Brand, $($Generics),+> Kind<($($Generics,)+)> for Brand
    |                                     ^^^^^^^^^^^^^^^^^^^^^^     ^^^^^
45  |         where
46  |             Brand: $KindN<$($Generics),+>,
    |                    ---------------------- unsatisfied trait bound introduced here
...
210 | make_trait_kind!(Kind1, Apply1, "* -> *", (A));
    | ---------------------------------------------- in this macro invocation
    = note: the full name for the type has been written to '/playground/target/debug/deps/playground-0397c81c81221729.long-type-1043842649665829542.txt'
    = note: consider using `--verbose` to print the full type name to the console
    = note: this error originates in the macro `make_trait_kind` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `F` with trait `Kind1`
    |
696 |         F: 'a + Kind<(B,)> + Kind<(Apply<Self, (B,)>,)> + Applicative + Kind1<std::sync::Arc<(dyn std::ops::Fn(<VecBrand as Kind<(A,)>>::Output) -> <VecBrand as Kind<(A,)>>::Output + 'a)>>,
    |                                                                       ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `F: Kind1<Arc<dyn Fn(<VecBrand as Kind<(B,)>>::Output) -> ...>>` is not satisfied
   --> src/lib.rs:733:27
    |
733 |                       let map_cons_f_head: Apply<
    |  __________________________________________^
734 | |                         F,
735 | |                         (ClonableFn<'a, Apply<Self, (B,)>, Apply<Self, (B,)>>,),
736 | |                     > = map_cons(f_head);
    | |_____________________^ the trait `Kind1<Arc<(dyn Fn(<VecBrand as Kind<(B,)>>::Output) -> <VecBrand as Kind<(B,)>>::Output + 'a)>>` is not implemented for `F`
    |
note: required for `F` to implement `Kind<(Arc<(dyn Fn(<VecBrand as Kind<(B,)>>::Output) -> <VecBrand as Kind<(B,)>>::Output + 'a)>,)>`
   --> src/lib.rs:44:31
    |
44  |         impl<Brand, $($Generics),+> Kind<($($Generics,)+)> for Brand
    |                                     ^^^^^^^^^^^^^^^^^^^^^^     ^^^^^
45  |         where
46  |             Brand: $KindN<$($Generics),+>,
    |                    ---------------------- unsatisfied trait bound introduced here
...
210 | make_trait_kind!(Kind1, Apply1, "* -> *", (A));
    | ---------------------------------------------- in this macro invocation
    = note: the full name for the type has been written to '/playground/target/debug/deps/playground-0397c81c81221729.long-type-13968914865257356677.txt'
    = note: consider using `--verbose` to print the full type name to the console
    = note: this error originates in the macro `make_trait_kind` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `F` with trait `Kind1`
    |
696 |         F: 'a + Kind<(B,)> + Kind<(Apply<Self, (B,)>,)> + Applicative + Kind1<std::sync::Arc<(dyn std::ops::Fn(<VecBrand as Kind<(B,)>>::Output) -> <VecBrand as Kind<(B,)>>::Output + 'a)>>,
    |                                                                       ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (lib) due to 3 previous errors

But this seems to me to be overly specific to this particular implementation of the trait, so I'm wondering if there's a more general solution I could look into.

I've asked an LLM for some ideas, but I think my particular issue is too advanced and in the weeds for myself so I can't tell if the solutions and ideas it's offering are correct or even relevant. As such, I'd greatly appreciate it if a real human expert can weigh in on the topic and verify (or deny) its suggestions and/or offer alternative solutions/ideas I can look into.

I got around the issue by using GATs for the HKT machinery which allowed me to not have to keep adding more trait bound constraints to the typeclasses and also allowed me to remove a lot of the explicit type annotations in the implementations.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.