Syntax for a trait on a generic type with parameters

I have structs with parameters, like Foo<T> and Bar<T>, and I would like to write a trait that works for any one of them, and allows them to convert the type of their parameter T to U.

edit: see code below

fn transmogrify(from: X<T>) -> X<U>;

where X can be Foo or Bar (or anything else that implements the trait), and T and U can be any type. I'm a bit lost in the number and nesting of <> that I need.

This doesn't parse:

trait Transmogrify<X<T>> {
    fn transmogrify<U>(self) -> X<U>;
}

What's the valid syntax?

You appear to be looking for HKT. Rust doesn't have support for that yet and, unfortunately, probably won't for a while.

https://github.com/rust-lang/rfcs/issues/324

I probably wasn't explaining it right, as I've confused myself with all this genericness :slight_smile:

I ended up with something like this:



pub trait Transmogrify<DestType, SrcParameter, DestParameter>
    where Self: ParameterToSlice<SrcParameter>,
          DestType: ParameterFromSlice<DestParameter> {
    fn transmogrify<Callback>(&self, mut f: Callback) -> DestType
        where Callback: FnMut(SrcParameter) -> DestParameter;
}

impl<SrcType, DestType, SrcParameter: Clone, DestParameter: Clone> Transmogrify<DestType, SrcParameter, DestParameter> for SrcType
    where SrcType: ParameterToSlice<SrcParameter>,
          DestType: ParameterFromSlice<DestParameter> {
    fn transmogrify<Callback>(&self, f: Callback) -> DestType
        where Callback: FnMut(SrcParameter) -> DestParameter  {
            let Parameters:Vec<DestParameter> = self.as_slice().iter().cloned().map(f).collect();
            DestType::from_slice(&Parameters)
    }
}

which does work, but it's not as constrained as I'd like, as it allows anything -> anything conversion, so Rust demands type hints.