Last active
October 29, 2021 23:09
-
-
Save AnthonyMikh/f5b6beb3f5af0cc3ce9ada13c55754a6 to your computer and use it in GitHub Desktop.
Illustration of composable parametrized behavior in Rust
This file contains 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 Provide<Item, Path> { | |
fn provide(&mut self) -> Item; | |
} | |
struct Itself; | |
struct Head<T>(T); | |
struct Tail<T>(T); | |
struct HNil; | |
struct HCons<H, T>(H, T); | |
impl<Item, H, T, HSource> Provide<Item, Head<HSource>> for HCons<H, T> | |
where | |
H: Provide<Item, HSource>, | |
{ | |
fn provide(&mut self) -> Item { | |
self.0.provide() | |
} | |
} | |
impl<Item, H, T, TSource> Provide<Item, Tail<TSource>> for HCons<H, T> | |
where | |
T: Provide<Item, TSource>, | |
{ | |
fn provide(&mut self) -> Item { | |
self.1.provide() | |
} | |
} | |
trait ProvideExt<T> { | |
fn provide_via_path<P>(&mut self) -> T | |
where | |
Self: Provide<T, P>; | |
} | |
impl<Item, T> ProvideExt<Item> for T { | |
fn provide_via_path<P>(&mut self) -> Item | |
where | |
Self: Provide<Item, P>, | |
{ | |
self.provide() | |
} | |
} | |
trait ProvideBase<Item> { | |
fn provide_base(&mut self) -> Item; | |
} | |
impl<Item, T> Provide<Item, Itself> for T | |
where | |
T: ProvideBase<Item>, | |
{ | |
fn provide(&mut self) -> Item { | |
self.provide_base() | |
} | |
} | |
struct Cloning<T>(T); | |
impl<T> ProvideBase<T> for Cloning<T> | |
where | |
T: Clone, | |
{ | |
fn provide_base(&mut self) -> T { | |
self.0.clone() | |
} | |
} | |
struct TheAnswer; | |
impl ProvideBase<u32> for TheAnswer { | |
fn provide_base(&mut self) -> u32 { | |
42 | |
} | |
} | |
fn _test() { | |
let mut list = HCons(Cloning(0), HCons(Cloning(()), HNil)); | |
let _: u32 = list.provide(); | |
let _: () = list.provide(); | |
let mut list = HCons(TheAnswer, HCons(Cloning(0), HNil)); | |
let _ = list.provide_via_path::<Head<Itself>>(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment