LINUX.ORG.RU

История изменений

Исправление red75prim, (текущая версия) :

Я не говорил, что в расте будет удобно писать. Или что можно сделать совсем-совсем всё на текущем этапе реализации раста. Здесь для нормального вывода тупла нужна специализация например.

Но такие представления туплов математически эквиваленты. Нельзя придумать пример, который я не смогу написать на расте.

Ссылка на плейграунд

#![feature(specialization)]
#![allow(incomplete_features)]
use std::fmt::Debug;

macro_rules! tuple {
    ($e:expr, $( $rest:expr ),+) => { ($e, tuple!($( $rest ),+)) };
    ($e:expr) => { ($e, ()) };
    ($e:expr,) => { ($e, ()) };
    () => { () };
}

fn main() {
    let a = tuple!(1, '%', 4);
    let b = tuple!("string", tuple!(), true);
    let c = tuple!(tuple!(0.256));
    let d = tuple!(a, b, c).concat_all();
    d.start_iter(); // (1 '%' 4 "string" () true (0.256 ))
}

trait Concat<V> {
    type Out;
    fn concat(self, other: V) -> Self::Out;
}

impl<V, T, U: Concat<V>> Concat<V> for (T, U) {
    type Out = (T, U::Out);
    fn concat(self, other: V) -> Self::Out {
        (self.0, self.1.concat(other))
    }
}

impl<V> Concat<V> for () {
    type Out = V;
    fn concat(self, other: V) -> Self::Out {
        other
    }
}

trait ConcatAll {
    type Out;
    fn concat_all(self) -> Self::Out;
}

impl<T: Concat<U::Out>, U: ConcatAll> ConcatAll for (T, U) {
    type Out = T::Out;
    fn concat_all(self) -> Self::Out {
        self.0.concat(self.1.concat_all())
    }
}

impl ConcatAll for () {
    type Out = ();
    fn concat_all(self) -> () {
        ()
    }
}

trait IterTuple {
    fn start_iter(&self);
    fn iter(&self);
}

impl<T: Debug> IterTuple for T {
    default fn start_iter(&self) {
        print!("{:?} ", self)
    }
    default fn iter(&self) {
        print!("{:?} ", self)
    }
}

impl<T: IterTuple + Debug, U: IterTuple + Debug> IterTuple for (T, U) {
    fn start_iter(&self) {
        print!("(");
        self.0.start_iter();
        self.1.iter();
        print!(")");
    }
    fn iter(&self) {
        self.0.start_iter();
        self.1.iter();
    }
}

impl IterTuple for () {
    fn start_iter(&self) {
        print!("() ");
    }
    fn iter(&self) {
    }
}

Исходная версия red75prim, :

Я не говорил, что в расте будет удобно писать. Или что можно сделать совсем-совсем всё на текущем этапе реализации раста. Здесь для нормального вывода тупла нужна специализация например.

Но такие представления туплов математически эквиваленты. Нельзя придумать пример, который я не смогу написать на расте.

Ссылка на плейграунд

#![feature(specialization)]
#![allow(incomplete_features)]
use std::fmt::Debug;

macro_rules! tuple {
    ($e:expr, $( $rest:expr ),+) => {
        ($e, tuple!($( $rest ),+))
    };
    ($e:expr) => {
        ($e, ())
    };
    ($e:expr,) => {
        ($e, ())
    };
    () => {
        ()  
    };
}

fn main() {
    let a = tuple!(1, '%', 4);
    let b = tuple!("string", tuple!(), true);
    let c = tuple!(tuple!(0.256));
    let d = tuple!(a, b, c).concat_all();
    d.start_iter(); // (1 '%' 4 "string" () true (0.256 ))
}

trait Concat<V> {
    type Out;
    fn concat(self, other: V) -> Self::Out;
}

impl<V, T, U: Concat<V>> Concat<V> for (T, U) {
    type Out = (T, U::Out);
    fn concat(self, other: V) -> Self::Out {
        (self.0, self.1.concat(other))
    }
}

impl<V> Concat<V> for () {
    type Out = V;
    fn concat(self, other: V) -> Self::Out {
        other
    }
}

trait ConcatAll {
    type Out;
    fn concat_all(self) -> Self::Out;
}

impl<T: Concat<U::Out>, U: ConcatAll> ConcatAll for (T, U) {
    type Out = T::Out;
    fn concat_all(self) -> Self::Out {
        self.0.concat(self.1.concat_all())
    }
}

impl ConcatAll for () {
    type Out = ();
    fn concat_all(self) -> () {
        ()
    }
}

trait IterTuple {
    fn start_iter(&self);
    fn iter(&self);
}

impl<T: Debug> IterTuple for T {
    default fn start_iter(&self) {
        print!("{:?} ", self)
    }
    default fn iter(&self) {
        print!("{:?} ", self)
    }
}

impl<T: IterTuple + Debug, U: IterTuple + Debug> IterTuple for (T, U) {
    fn start_iter(&self) {
        print!("(");
        self.0.start_iter();
        self.1.iter();
        print!(")");
    }
    fn iter(&self) {
        self.0.start_iter();
        self.1.iter();
    }
}

impl IterTuple for () {
    fn start_iter(&self) {
        print!("() ");
    }
    fn iter(&self) {
    }
}