Write the equivalent of Option's "map" for custom type

Hello! I would like some help figuring out how to write this bit of code, if possible :smile:

I am designing an API where the presence of type substitution is denoted at the type level.

I have this generic container type:

struct Substituted<T> {
    inner: T,
    marker: bool,

and the function signatures in this API take this Substituted type:

struct Data {
  inner: u64

fn api_method(data: Substituted<Data>) -> Substituted<u64> {
  // I want to put a map method here
  // to map Substituted<T> -> Substituted<U>
  // I want to do this:
  // data.map(|d| d.inner)

I've attempted to model this method after the implementation for Option, however for this API I cannot use nightly Rust, so I am running into some snags. Do y'all have any suggestions for how I might go around this?

Here's what I have so far:

impl<T> Substituted<T> {
    pub const fn map<U, F>(self, f: F) -> Substituted<U>
        F: FnOnce(T) -> U,
        let Substituted { inner, marker } = self;
        Substituted::new(f(inner), marker)

I'm getting this error:

the trait bound `F: std::ops::FnOnce<(T,)>` is not satisfied
expected an `FnOnce<(T,)>` closure, found `F`rustcClick for full compiler diagnostic
substituted.rs(52, 26): the trait `std::ops::FnOnce<(T,)>` is implemented for `F`, but that implementation is not `const`
substituted.rs(49, 26): consider further restricting this bound: ` + ~const std::ops::FnOnce<(T,)>`

Just figured it out... the problem is solved by removing const from the signature for map :upside_down_face:

For the record, in future it'd be better to use the error from cargo check, not from IDE. In this case, it would look like this:

error[E0277]: the trait bound `F: FnOnce<(T,)>` is not satisfied
  --> src/lib.rs:12:26
12 |         Substituted::new(f(inner), marker)
   |                          ^^^^^^^^ expected an `FnOnce<(T,)>` closure, found `F`
note: the trait `FnOnce<(T,)>` is implemented for `F`, but that implementation is not `const`
  --> src/lib.rs:12:26
12 |         Substituted::new(f(inner), marker)
   |                          ^^^^^^^^
help: consider further restricting this bound
9  |         F: FnOnce(T) -> U + ~const std::ops::FnOnce<(T,)>,
   |                           +++++++++++++++++++++++++++++++

...which probably is a little more readable (and sometimes more complete) then the IDE-adapted one.

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.