Last active
February 10, 2021 15:45
-
-
Save fero23/479f5ceaad4bfa43e64026f2ab402b35 to your computer and use it in GitHub Desktop.
Another take on higher kinded types for Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait HKT<N> { | |
type C; | |
type NC; | |
} | |
trait Functor<N>: HKT<N> { | |
fn fmap<F: Fn(&Self::C) -> N>(&self, f: F) -> Self::NC; | |
} | |
impl<C, N> HKT<N> for Option<C> { | |
type C = C; | |
type NC = Option<N>; | |
} | |
impl<T, N> Functor<N> for Option<T> { | |
fn fmap<F: Fn(&Self::C) -> N>(&self, f: F) -> Option<N> { | |
self.as_ref().map(f) | |
} | |
} | |
impl<C, N> HKT<N> for Vec<C> { | |
type C = C; | |
type NC = Vec<N>; | |
} | |
impl<T, N> Functor<N> for Vec<T> { | |
fn fmap<F: Fn(&Self::C) -> N>(&self, f: F) -> Vec<N> { | |
self.iter().map(|t| f(t)).collect() | |
} | |
} | |
#[derive(Debug)] | |
struct FunctorContainer<F>(F); | |
impl<N, F: Functor<N>> HKT<N> for FunctorContainer<F> { | |
type C = F::C; | |
type NC = FunctorContainer<F::NC>; | |
} | |
impl<N, FT: Functor<N>> Functor<N> for FunctorContainer<FT> { | |
fn fmap<F: Fn(&Self::C) -> N>(&self, f: F) -> Self::NC { | |
FunctorContainer(self.0.fmap(f)) | |
} | |
} | |
fn main() { | |
let fc1 = FunctorContainer(Some(42)); | |
let fc2 = FunctorContainer(vec![1,2,3,4,5]); | |
println!("{:?} {:?}", | |
fc1.fmap(|n| n.to_string()), | |
fc2.fmap(|n| n.to_string())); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment