Skip to content

Instantly share code, notes, and snippets.

@Sgeo
Created March 26, 2016 04:22
Show Gist options
  • Select an option

  • Save Sgeo/25c2794d32d64b2b43eb to your computer and use it in GitHub Desktop.

Select an option

Save Sgeo/25c2794d32d64b2b43eb to your computer and use it in GitHub Desktop.
trait HKT<U> {
type Base;
type Reapplied;
}
type BaseOf<T> = <T as HKT<()>>::Base;
type Reapply<T, U> = <T as HKT<U>>::Reapplied;
impl<'a, T, U: 'a> HKT<U> for &'a T {
type Base = T;
type Reapplied = &'a U;
}
impl<'a, T, U: 'a> HKT<U> for &'a mut T {
type Base = T;
type Reapplied = &'a mut U;
}
trait Ref<'a, T: 'a, R: 'a>: HKT<R> {
fn consume<Fi, Fm>(s: Self, fi: Fi, fm: Fm) -> Reapply<Self, R>
where Fi: FnOnce(&'a T) -> &'a R,
Fm: FnOnce(&'a mut T) -> &'a mut R;
}
impl<'a, T: 'a, R: 'a> Ref<'a, T, R> for &'a T {
fn consume<Fi, Fm>(s: Self, fi: Fi, _fm: Fm) -> Reapply<Self, R>
where Fi: FnOnce(&'a T) -> &'a R,
Fm: FnOnce(&'a mut T) -> &'a mut R {
fi(s)
}
}
impl<'a, T: 'a, R: 'a> Ref<'a, T, R> for &'a mut T {
fn consume<Fi, Fm>(s: Self, _fi: Fi, fm: Fm) -> Reapply<Self, R>
where Fi: FnOnce(&'a T) -> &'a R,
Fm: FnOnce(&'a mut T) -> &'a mut R {
fm(s)
}
}
fn main() {
struct Foo {
a: i32
}
impl Foo {
fn a_ref<'a, S: Ref<'a, Foo, i32>>(s: S) -> Reapply<S, i32> {
Ref::consume(s, |r| &r.a, |r| &mut r.a)
}
}
let mut foo = Foo { a: 0 };
{
println!("{:?}", Foo::a_ref(&foo));
}
{
*Foo::a_ref(&mut foo) = 5;
}
{
println!("{:?}", Foo::a_ref(&foo));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment