<p>In programming languages like Rust, variables of different types that implement the same trait can have different sizes, i.e., the number of bytes used in the memory representation of the type. For example, both <code>Map&lt;I, F&gt;</code> and <code>Filter&lt;I, P&gt;</code> implement the <code>Iterator</code> trait but differ in size. This make it hard to implement <code>Functor</code> for the types implementing <code>Iterator</code>.</p>
<p>Assuming the Rust language already supports &quot;higher-ranked types,&quot; I would like to design a <code>Functor</code> trait. However, attempting to implement this trait for the <code>Iterator</code> trait directly as shown below would not work:</p>
<pre class="lang-rust prettyprint-override"><code>trait Functor&lt;F&lt;_&gt;&gt; {
    fn map&lt;A, B&gt;(this: F&lt;A&gt;, f: impl Fn(A) -&gt; B) -&gt; F&lt;B&gt;;
}
</code></pre>
<p>The reason is that <code>Iterator</code> is a trait and not a type constructor, where <code>Functor</code> take a type constructor as input. Consequently, we cannot write something like <code>Functor&lt;Iterator&gt;</code>.</p>

<functional-programming><rust><applicative-functors>
How can I design a Functor trait to handle trait?
CC BY-SA 4.0
2023-08-22T05:39:34.653Z
Hi there, welcome to the Programming Language Design and Implementation StackExchange! Currently, it seems there isn't an answerable question being asked here, as it reads as just statements. Editing your question to ask a specific question would greatly help people know how to answer your question.
lyxal
CC BY-SA 4.0
2023-08-22T05:47:26.913Z
Is this about *applicative* functors, like in the tags, or just functors like the body?  Is it about needing higher-kinded types (to express the same-container, different-contents relationship), or about varying memory allocations? Is it particularly focused on the full Rust language model, or on designing support for functional types in languages more generally? You can [edit] your question to be explicit about what you're looking for.
Michael Homer
CC BY-SA 4.0
2023-08-22T06:02:16.957Z
What does "size" mean in this context?
David Young
CC BY-SA 4.0
2023-08-22T12:10:28.183Z
"Size" here means the number of bytes used in the type's memory representation.
kaya3
CC BY-SA 4.0
2023-08-22T12:14:43.567Z
@DavidYoung pretty sure given that OP is referencing Rust it's how much memory the compiler has to allocate to hold the thing in question. I'm not sure what relevance that has to the question either. Although I don't really get the question, I'm not sure where OP got the idea that fmap can return arbitrary types.
Jared Smith
CC BY-SA 4.0
2023-08-22T12:36:35.023Z
Seems like the trait wants an [associated type](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types) (e.g. `trait F { type Output; ... }`), which is declared by the implementor.
kaya3
CC BY-SA 4.0
2023-08-22T15:59:19.863Z
This question is a strange mix of type theory and representation. While I could answer the representational part, I don't get the question on the type theory side, because I'd expect the type of the functor to be part of the trait's specification instead of the _. Maybe it's just a syntactical issue.
feldentm
CC BY-SA 4.0
2023-08-22T16:32:53.193Z
Ok, I think I understand a bit more now. In Haskell terms, you want to do something akin to `instance Functor Foldable where ...` (not that the particular example I gave there makes complete sense to write in Haskell). This seems like it would cause issues with type class resolution (and, I assume, trait resolution too but I don't really know Rust). Say you have two `Functor` implementations, one for trait `P` and one for trait `Q`. What if you have a type that implements both `P` and `Q`? Which `Functor` implementation gets used?
David Young
<p>Rust already has a way to represent <code>Functor</code> using <a href="https://rust-lang.github.io/generic-associated-types-initiative/explainer/motivation.html" rel="nofollow noreferrer">Generic Associated Types (GATs)</a>:</p>
<pre class="lang-rust prettyprint-override"><code>pub trait Functor&lt;A&gt; {
    type With&lt;B&gt;: Functor&lt;B&gt;;
    fn map&lt;B&gt;(self, f: impl Fn(A) -&gt; B) -&gt; Self::With&lt;B&gt;;
}
</code></pre>
<p>In this trait, <code>Self</code> is the functor type specialized to <code>A</code>, and <code>With&lt;B&gt;</code> is the functor type specialized to <code>B</code> (<code>With&lt;B&gt;</code> is how we emulate &quot;higher-kinded types&quot;). For example:</p>
<pre class="lang-rust prettyprint-override"><code>/// Dummy functor-able type
pub struct Foonctor&lt;A&gt;(Vec&lt;A&gt;, A);

impl&lt;A&gt; Functor&lt;A&gt; for Foonctor&lt;A&gt; {
    type With&lt;B&gt; = Foonctor&lt;B&gt;;
    fn map&lt;B&gt;(self, f: impl Fn(A) -&gt; B) -&gt; Self::With&lt;B&gt; {
        Foonctor(self.0.into_iter().map(&amp;f).collect(), f(self.1))
    }
}
</code></pre>
<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=c58a41625a364d242d3546bd0f40c8c2" rel="nofollow noreferrer">(playground link)</a></p>
<p>Interestingly enough, <strong>using only 2 tiny modifications, we can already make any <code>Iterator</code> implement <code>Functor</code></strong> via blanket <code>impl</code>. The first modification is to <strong>add the map function's type to <code>With</code>, making it <code>With&lt;F, B&gt;</code></strong>; the second modification is to <strong>make <code>With&lt;B&gt;</code> <em>not</em> the same type as <code>Self</code> but with a different parameter, but instead make it <a href="https://doc.rust-lang.org/std/iter/struct.Map.html" rel="nofollow noreferrer"><code>std::iter::Map&lt;Self, F&gt;</code></a></strong>:</p>
<pre class="lang-rust prettyprint-override"><code>/// New functor trait
pub trait Functor&lt;A&gt; {
    type With&lt;F: Fn(A) -&gt; B, B&gt; = Functor&lt;B&gt;;
    fn map&lt;F: Fn(A) -&gt; B, B&gt;(self, f: F) -&gt; Self::With&lt;F, B&gt;;
}

/// We can still implement the new trait wherever we could implement the old one
impl&lt;A&gt; Functor&lt;A&gt; for Foonctor&lt;A&gt; {
    type With&lt;F: Fn(A) -&gt; B, B&gt; = Foonctor&lt;B&gt;;
    fn map&lt;F: Fn(A) -&gt; B, B&gt;(self, f: F) -&gt; Self::With&lt;F, B&gt; {
        // Same exact implementation as before
        Foonctor(Iterator::map(self.0.into_iter(), &amp;f).collect(), f(self.1))
    }
}

/// But now we can also implement it for arbitrary iterators, using std::iter::Map
impl&lt;A, I: Iterator&lt;Item=A&gt;&gt; Functor&lt;A&gt; for I {
    type With&lt;F: Fn(A) -&gt; B, B&gt; = std::iter::Map&lt;I, F&gt;;
    fn map&lt;F: Fn(A) -&gt; B, B&gt;(self, f: F) -&gt; Self::With&lt;F, B&gt; {
        Iterator::map(self, f)
    }
}
</code></pre>
<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=b0cef5dfde3a44ab0c916ca443c7e7a0" rel="nofollow noreferrer">(playground link)</a></p>
<p>However, there's one problem with the above: <strong>the functor <code>impl</code> for the iterator trait is a <a href="https://stackoverflow.com/questions/73861891/what-are-blanket-implementations-in-rust">blanket <code>impl</code></a>, which <a href="https://stackoverflow.com/questions/73782573/why-do-blanket-implementations-for-two-different-traits-conflict">prevents <code>impl</code>s for other traits</a></strong>. There's a good reason for this: if <code>Functor</code> was blanket implemented for 2 traits, what implementation would an object which implements both traits choose? So until the <a href="https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md" rel="nofollow noreferrer">specialization RFC</a> gets accepted, this solution is non-ideal.</p>
<p>What we can do, though, is <strong>instead of implementing on the trait directly, use the <a href="https://rust-unofficial.github.io/patterns/patterns/behavioural/newtype.html" rel="nofollow noreferrer">newtype pattern</a> and implement it on the newtype</strong>. Then you can use newtypes for other traits as well (this sidesteps the ambiguity problem because even if an object implements multiple traits, you can only choose one newtype to wrap it with and must choose one explicitly)*:</p>
<pre class="lang-rust prettyprint-override"><code>/// Trait newtype
pub struct IteratorFunctor&lt;A, I: Iterator&lt;Item=A&gt;&gt;(I);

/// Another trait newtype
pub struct FutureFunctor&lt;A, Fut: futures::Future&lt;Output=A&gt;&gt;(Fut);

/// Emulate implementing functor for a trait, by implementing on its newtype
impl&lt;A, I: Iterator&lt;Item=A&gt;&gt; Functor&lt;A&gt; for IteratorFunctor&lt;A, I&gt; {
    /// Note that we also have to wrap the `With` type with the newtype
    type With&lt;F: Fn(A) -&gt; B, B&gt; = IteratorFunctor&lt;B, std::iter::Map&lt;I, F&gt;&gt;;
    fn map&lt;F: Fn(A) -&gt; B, B&gt;(self, f: F) -&gt; Self::With&lt;F, B&gt; {
        IteratorFunctor(self.0.map(f))
    }
}

/// Emulate implementing functor for another trait
impl&lt;A, Fut: futures::Future&lt;Output=A&gt;&gt; Functor&lt;A&gt; for FutureFunctor&lt;A, Fut&gt; {
    type With&lt;F: Fn(A) -&gt; B, B&gt; = FutureFunctor&lt;B, futures::future::Map&lt;Fut, F&gt;&gt;;
    fn map&lt;F: Fn(A) -&gt; B, B&gt;(self, f: F) -&gt; Self::With&lt;F, B&gt; {
        use futures::future::FutureExt;
        FutureFunctor(self.0.map(f))
    }
}

/// Demo
fn main() {
    // Iterator example: [1, 2, ... 10]
    let elems = 1..=10;
    // map (* 2) elems
    let mapped_elems = IteratorFunctor(elems).map(|e| e * 2).0;
    // [2, 4, ... 20]
    println!(&quot;{:?}&quot;, mapped_elems.collect::&lt;Vec&lt;_&gt;&gt;());
    
    // Future example: { &lt;complex calculation&gt; = &quot;complex calculated value&quot; }
    let future = async {
        // Pretend we're douing some complex calculation with `.await`s here
        &quot;complex calculated value&quot;
    };
    // map length future
    let mapped_future = FutureFunctor(future).map(|f| f.len()).0;
    // { &lt;complex calculation |&gt; length&gt; = 24 }
    println!(&quot;{:?}&quot;, futures::executor::block_on(mapped_future));
}
</code></pre>
<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=edace1c64f594f26a10d909f14382667" rel="nofollow noreferrer">Here's the complete finished code (playground link)</a></p>
<hr />
<p>* (In our specific example, this also makes it easier to demo actually using the trait, because <code>Iterator::map</code> is already defined. If we demo'd the second-last example, we'd have to explicitly call <code>Functor::map</code>, like how we explicitly called <code>Iterator::map</code> in the <code>Foonctor</code> impl. This isn't an issue for every blanket <code>impl</code> in general, it just so happens to be here, because <code>Functor</code> isn't the only in-scope trait which defines a method named <code>map</code>)</p>
<p>Also, for why this works even though Rust trait implementations can be different sizes: the size of <code>std::iter::Map&lt;I, F&gt;</code> is the size of whatever <code>I</code> it's given plus the size of <code>F</code>. If we call <code>Functor::map</code> twice we'll get <code>IteratorFunctor&lt;C, Map&lt;Map&lt;I, F0&gt;, F1&gt;&gt;</code>, 3 times and we'll get <code>IteratorFunctor&lt;D, Map&lt;Map&lt;Map&lt;I, F0&gt;, F1&gt;, F2&gt;&gt;</code>, etc.; all these types have different sizes, but they're all represented at compile-time and their sizes are known at compile-time.</p>
<p><strong>If you're doing something where the compiler doesn't know how many times <code>map</code> will be called at compile time (e.g. call <code>map</code> in a loop): you can convert any iterator into a <code>Box&lt;dyn Iterator&lt;Item=A&gt;&gt;</code>, slightly modify <code>Functor</code> again (add a lifetime to <code>With</code> which bounds <code>F</code>), and add another newtype wrapper which returns the same type given the same type parameter:</strong></p>
<pre class="lang-rust prettyprint-override"><code>pub trait Functor&lt;A&gt; {
    /// New modification: we have to add a lifetime parameter and bound `F` by it
    type With&lt;'b, F: Fn(A) -&gt; B + 'b, B&gt;: Functor&lt;B&gt; where Self: 'b;
    fn map&lt;'b, F: Fn(A) -&gt; B + 'b, B&gt;(self, f: F) -&gt; Self::With&lt;'b, F, B&gt; where Self: 'b;
}

/// This wrapper doesn't contain the iterator, so we can erase the `std::iter::Map` wrappers.
/// The underlying iterator is allocated on the heap so we don't need to know its size
/// (i.e. how many times `map` was called) at compile-time
pub struct BoxIteratorFunctor&lt;'a, A&gt;(Box&lt;dyn Iterator&lt;Item=A&gt; + 'a&gt;);

impl&lt;'a, A&gt; Functor&lt;A&gt; for BoxIteratorFunctor&lt;'a, A&gt; {
    /// No `std::iter::Map` or `F` in the result type
    type With&lt;'b, F: Fn(A) -&gt; B + 'b, B&gt; = BoxIteratorFunctor&lt;'b, B&gt; where Self: 'b;
    fn map&lt;'b, F: Fn(A) -&gt; B + 'b, B&gt;(self, f: F) -&gt; Self::With&lt;'b, F, B&gt; where Self: 'b {
        BoxIteratorFunctor(Box::new(self.0.map(f)))
    }
}

/// Demo
fn main() {
    // Iterator example: [1, 2, ... 10]
    let mut elems = BoxIteratorFunctor(Box::new(1u64..=10));
    for _ in 1..5 {
        // map (^ 2) elems
        // We can assign to the same variable, because it's the same type:
        //     `BoxIteratorFunctor&lt;'static, u64&gt;`
        elems = elems.map(move |e| e * e);
    }
    // [((((1^2)^2)^2)^2)^2, ((((2^2)^2)^2)^2)^2 ... ((((10^2)^2)^2)^2)^2]
    println!(&quot;{:?}&quot;, elems.0.collect::&lt;Vec&lt;_&gt;&gt;());
}
</code></pre>
<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=c98f5063871d2e0659d3fba387b2a805" rel="nofollow noreferrer">(playground)</a></p>

CC BY-SA 4.0
2023-08-23T06:43:46.120Z
2023-08-23T06:43:46.120Z
tarzh
CC BY-SA 4.0
2023-08-25T07:14:27.970Z
Excellent job! However, I must point out that with this approach, we can't implement the Functor trait for `Iterator`, `Future`, and `Option` all at once...
Jw C
CC BY-SA 4.0
2023-08-25T15:43:47.787Z
Not unless we wrap the `Iterator` and `Future` in newtypes to call `Functor` operations on them, but if we do then it's possible: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b4c68361aa3554094209992ef5edfb30
tarzh
CC BY-SA 4.0
2023-08-27T08:43:21.800Z
There is still one major drawback of this approach: there is no way to constraint the `With<F, B>` has the same type or implement the trait as the implementer. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=570aea7af28f877e739e4c2f5b20ce8d
Jw C
# How can I design a Functor trait to handle trait?
Posted by: username_0 on 2023-08-22
In programming languages like Rust, variables of different types that implement the same trait can have different sizes, i.e., the number of bytes used in the memory representation of the type. For example, both Map and Filter implement the Iterator trait but differ in size. This make it hard to implement Functor for the types implementing Iterator.
Assuming the Rust language already supports "higher-ranked types," I would like to design a Functor trait. However, attempting to implement this trait for the Iterator trait directly as shown below would not work:
trait Functor> {
    fn map(this: F, f: impl Fn(A) -> B) -> F;
}

The reason is that Iterator is a trait and not a type constructor, where Functor take a type constructor as input. Consequently, we cannot write something like Functor.
**Tags:** functional-programming rust applicative-functors
> **Comments:**
> **username_1**: Hi there, welcome to the Programming Language Design and Implementation StackExchange! Currently, it seems there isn't an answerable question being asked here, as it reads as just statements. Editing your question to ask a specific question would greatly help people know how to answer your question.  
> **username_2**: Is this about *applicative* functors, like in the tags, or just functors like the body?  Is it about needing higher-kinded types (to express the same-container, different-contents relationship), or about varying memory allocations? Is it particularly focused on the full Rust language model, or on designing support for functional types in languages more generally? You can [edit] your question to be explicit about what you're looking for.  
> **username_3**: What does "size" mean in this context?  
> **username_4**: "Size" here means the number of bytes used in the type's memory representation.  
> **username_5**: @DavidYoung pretty sure given that OP is referencing Rust it's how much memory the compiler has to allocate to hold the thing in question. I'm not sure what relevance that has to the question either. Although I don't really get the question, I'm not sure where OP got the idea that fmap can return arbitrary types.  
> **username_4**: Seems like the trait wants an [associated type](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types) (e.g. `trait F { type Output; ... }`), which is declared by the implementor.  
> **username_6**: This question is a strange mix of type theory and representation. While I could answer the representational part, I don't get the question on the type theory side, because I'd expect the type of the functor to be part of the trait's specification instead of the _. Maybe it's just a syntactical issue.  
> **username_3**: Ok, I think I understand a bit more now. In Haskell terms, you want to do something akin to `instance Functor Foldable where ...` (not that the particular example I gave there makes complete sense to write in Haskell). This seems like it would cause issues with type class resolution (and, I assume, trait resolution too but I don't really know Rust). Say you have two `Functor` implementations, one for trait `P` and one for trait `Q`. What if you have a type that implements both `P` and `Q`? Which `Functor` implementation gets used?  
---
## 1 answers
### Answer by username_7 on 2023-08-23. Score: 4 | Accepted answer
Rust already has a way to represent Functor using Generic Associated Types (GATs):
pub trait Functor {
    type With: Functor;
    fn map(self, f: impl Fn(A) -> B) -> Self::With;
}

In this trait, Self is the functor type specialized to A, and With is the functor type specialized to B (With is how we emulate "higher-kinded types"). For example:
/// Dummy functor-able type
pub struct Foonctor(Vec, A);

impl Functor for Foonctor {
    type With = Foonctor;
    fn map(self, f: impl Fn(A) -> B) -> Self::With {
        Foonctor(self.0.into_iter().map(&f).collect(), f(self.1))
    }
}

(playground link)
Interestingly enough, using only 2 tiny modifications, we can already make any Iterator implement Functor via blanket impl. The first modification is to add the map function's type to With, making it With; the second modification is to make With not the same type as Self but with a different parameter, but instead make it std::iter::Map:
/// New functor trait
pub trait Functor {
    type With B, B> = Functor;
    fn map B, B>(self, f: F) -> Self::With;
}

/// We can still implement the new trait wherever we could implement the old one
impl Functor for Foonctor {
    type With B, B> = Foonctor;
    fn map B, B>(self, f: F) -> Self::With {
        // Same exact implementation as before
        Foonctor(Iterator::map(self.0.into_iter(), &f).collect(), f(self.1))
    }
}

/// But now we can also implement it for arbitrary iterators, using std::iter::Map
impl> Functor for I {
    type With B, B> = std::iter::Map;
    fn map B, B>(self, f: F) -> Self::With {
        Iterator::map(self, f)
    }
}

(playground link)
However, there's one problem with the above: the functor impl for the iterator trait is a blanket impl, which prevents impls for other traits. There's a good reason for this: if Functor was blanket implemented for 2 traits, what implementation would an object which implements both traits choose? So until the specialization RFC gets accepted, this solution is non-ideal.
What we can do, though, is instead of implementing on the trait directly, use the newtype pattern and implement it on the newtype. Then you can use newtypes for other traits as well (this sidesteps the ambiguity problem because even if an object implements multiple traits, you can only choose one newtype to wrap it with and must choose one explicitly)*:
/// Trait newtype
pub struct IteratorFunctor>(I);

/// Another trait newtype
pub struct FutureFunctor>(Fut);

/// Emulate implementing functor for a trait, by implementing on its newtype
impl> Functor for IteratorFunctor {
    /// Note that we also have to wrap the `With` type with the newtype
    type With B, B> = IteratorFunctor>;
    fn map B, B>(self, f: F) -> Self::With {
        IteratorFunctor(self.0.map(f))
    }
}

/// Emulate implementing functor for another trait
impl> Functor for FutureFunctor {
    type With B, B> = FutureFunctor>;
    fn map B, B>(self, f: F) -> Self::With {
        use futures::future::FutureExt;
        FutureFunctor(self.0.map(f))
    }
}

/// Demo
fn main() {
    // Iterator example: [1, 2, ... 10]
    let elems = 1..=10;
    // map (* 2) elems
    let mapped_elems = IteratorFunctor(elems).map(|e| e * 2).0;
    // [2, 4, ... 20]
    println!("{:?}", mapped_elems.collect::>());
    
    // Future example: {  = "complex calculated value" }
    let future = async {
        // Pretend we're douing some complex calculation with `.await`s here
        "complex calculated value"
    };
    // map length future
    let mapped_future = FutureFunctor(future).map(|f| f.len()).0;
    // {  length> = 24 }
    println!("{:?}", futures::executor::block_on(mapped_future));
}

Here's the complete finished code (playground link)

* (In our specific example, this also makes it easier to demo actually using the trait, because Iterator::map is already defined. If we demo'd the second-last example, we'd have to explicitly call Functor::map, like how we explicitly called Iterator::map in the Foonctor impl. This isn't an issue for every blanket impl in general, it just so happens to be here, because Functor isn't the only in-scope trait which defines a method named map)
Also, for why this works even though Rust trait implementations can be different sizes: the size of std::iter::Map is the size of whatever I it's given plus the size of F. If we call Functor::map twice we'll get IteratorFunctor, F1>>, 3 times and we'll get IteratorFunctor, F1>, F2>>, etc.; all these types have different sizes, but they're all represented at compile-time and their sizes are known at compile-time.
If you're doing something where the compiler doesn't know how many times map will be called at compile time (e.g. call map in a loop): you can convert any iterator into a Box>, slightly modify Functor again (add a lifetime to With which bounds F), and add another newtype wrapper which returns the same type given the same type parameter:
pub trait Functor {
    /// New modification: we have to add a lifetime parameter and bound `F` by it
    type With<'b, F: Fn(A) -> B + 'b, B>: Functor where Self: 'b;
    fn map<'b, F: Fn(A) -> B + 'b, B>(self, f: F) -> Self::With<'b, F, B> where Self: 'b;
}

/// This wrapper doesn't contain the iterator, so we can erase the `std::iter::Map` wrappers.
/// The underlying iterator is allocated on the heap so we don't need to know its size
/// (i.e. how many times `map` was called) at compile-time
pub struct BoxIteratorFunctor<'a, A>(Box + 'a>);

impl<'a, A> Functor for BoxIteratorFunctor<'a, A> {
    /// No `std::iter::Map` or `F` in the result type
    type With<'b, F: Fn(A) -> B + 'b, B> = BoxIteratorFunctor<'b, B> where Self: 'b;
    fn map<'b, F: Fn(A) -> B + 'b, B>(self, f: F) -> Self::With<'b, F, B> where Self: 'b {
        BoxIteratorFunctor(Box::new(self.0.map(f)))
    }
}

/// Demo
fn main() {
    // Iterator example: [1, 2, ... 10]
    let mut elems = BoxIteratorFunctor(Box::new(1u64..=10));
    for _ in 1..5 {
        // map (^ 2) elems
        // We can assign to the same variable, because it's the same type:
        //     `BoxIteratorFunctor<'static, u64>`
        elems = elems.map(move |e| e * e);
    }
    // [((((1^2)^2)^2)^2)^2, ((((2^2)^2)^2)^2)^2 ... ((((10^2)^2)^2)^2)^2]
    println!("{:?}", elems.0.collect::>());
}

(playground)
> **Comments:**
> **username_0** (2023-08-25): Excellent job! However, I must point out that with this approach, we can't implement the Functor trait for `Iterator`, `Future`, and `Option` all at once...  
> **username_7** (2023-08-25): Not unless we wrap the `Iterator` and `Future` in newtypes to call `Functor` operations on them, but if we do then it's possible: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b4c68361aa3554094209992ef5edfb30  
> **username_0** (2023-08-27): There is still one major drawback of this approach: there is no way to constraint the `With<F, B>` has the same type or implement the trait as the implementer. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=570aea7af28f877e739e4c2f5b20ce8d  
---
