Skip to content

Instantly share code, notes, and snippets.

@StephenWakely
Created November 3, 2022 22:26
Show Gist options
  • Save StephenWakely/ce8617c8dfa684e7a4421c32e37643f9 to your computer and use it in GitHub Desktop.
Save StephenWakely/ce8617c8dfa684e7a4421c32e37643f9 to your computer and use it in GitHub Desktop.
Functors in Rust
trait Functor<A> {
type Res<B>;
fn fmap<B, F: Fn(&A) -> B>(&self, f: F) -> Self::Res<B>;
}
impl<A> Functor<A> for Option<A> {
type Res<B> = Option<B>;
fn fmap<B, F: Fn(&A) -> B>(&self, f: F) -> Self::Res<B> {
match self {
Some(a) => Some(f(a)),
None => None,
}
}
}
impl<A> Functor<A> for Vec<A> {
type Res<B> = Vec<B>;
fn fmap<B, F: Fn(&A) -> B>(&self, f: F) -> Self::Res<B> {
self.iter().map(f).collect()
}
}
fn double_string<F, G>(param: F) -> G
where
F: Functor<usize, Res<String> = G>,
G: Functor<String>,
{
param.fmap(|n| (n * 2).to_string())
}
fn main() {
println!("{:?}", double_string(Some(32)));
println!("{:?}", double_string(vec![1, 2, 3, 4]));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment