Created
January 7, 2019 00:55
-
-
Save mikeyhew/af6eba0c6d450acdbb5faf0ffa6fd894 to your computer and use it in GitHub Desktop.
A potential new API for ty::Binder
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
/// A number of lifetime and type parameters that a type is bound with | |
#[derive(Copy, Clone, Debug)] | |
pub struct Binder { | |
num_lifetimes: u32, | |
num_types: u32, | |
} | |
impl Binder { | |
pub fn bind<T>(self, value: T) -> Bound<T> { | |
Bound { | |
binder: self, | |
value, | |
} | |
} | |
pub fn dummy() -> Self { | |
Self { | |
num_lifetimes: 0, | |
num_types: 0, | |
} | |
} | |
} | |
/// A bound type, e.g. `for<'a, T> &'a T`. Contains a Binder with the number of | |
/// lifetime and type parameters that it is bound with | |
#[derive(Copy, Clone, Debug)] | |
pub struct Bound<T> { | |
binder: Binder, | |
value: T, | |
} | |
impl<T> Bound<T> { | |
pub fn unbind(self) -> (Binder, T) { | |
(self.binder, self.value) | |
} | |
pub fn skip_binder(&self) -> &T { | |
&self.value | |
} | |
pub fn map_bound<U> (self, f: impl FnOnce(T) -> U) -> Bound<U> { | |
let (binder, value) = self.unbind(); | |
f(value).bind_with(binder) | |
} | |
} | |
pub trait Bind: Sized { | |
fn bind_with(self, binder: Binder) -> Bound<Self> { | |
Bound { | |
binder, | |
value: self, | |
} | |
} | |
fn bind_with_dummy(self) -> Bound<Self> { | |
self.bind_with(Binder::dummy()) | |
} | |
} | |
impl<T> Bind for T {} | |
fn main() { | |
let bound = "1".bind_with_dummy(); | |
let bound = bound.map_bound(|s| s.parse::<i32>().unwrap()); | |
println!("{:#?}", bound); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment