Skip to content

Instantly share code, notes, and snippets.

@bjorn3
Forked from rust-play/playground.rs
Created April 5, 2018 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bjorn3/969c1016d68f591525067e6d3103ad7a to your computer and use it in GitHub Desktop.
Save bjorn3/969c1016d68f591525067e6d3103ad7a to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
trait Kind<T> {
type Make;
}
enum OptionKind {}
impl<T> Kind<T> for OptionKind {
type Make = Option<T>;
}
trait FunctorKind<A, B>: Kind<A> + Kind<B> {
fn fmapk(<Self as Kind<A>>::Make, impl Fn(A) -> B) -> <Self as Kind<B>>::Make;
}
impl<A, B> FunctorKind<A, B> for OptionKind {
fn fmapk(me: Option<A>, f: impl Fn(A) -> B) -> Option<B> {
match me {
Some(m) => Some(f(m)),
None => None,
}
}
}
trait Functor<A, B>: Sized {
type Kind: FunctorKind<A, B>;
//type Item;
fn fmap(my: <Self::Kind as Kind<A>>::Make, f: impl Fn(A) -> B) -> <Self::Kind as Kind<B>>::Make {
Self::Kind::fmapk(my, f)
}
}
impl<A, B> Functor<A, B> for Option<A> {
type Kind = OptionKind;
}
fn main() {
println!("{:?}", OptionKind::fmapk(Some(10), |a| a + 1));
println!("{:?}", Option::fmap(Some(10), |a| a + 1));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment