Is it possible to parametrize returned type of a function?

It is related to my original question regarding parameterization with impl Trait.

How to write a function returning a value of type defined outside of the function?
Is it possible to adapt the code to reach the goal without using impl Trait and keeping control of returned type outside of the function?

use core::fmt::Display;

fn main() {
    let x = problem::<i32>();
    println!("{}", x);
    let x = problem::<i64>();
    println!("{}", x);
}

//

pub fn problem<ContainerEnd>() -> ContainerEnd
where
    ContainerEnd: Display,
{
    let on_end = 13;
    on_end
}

Playground

Well you could specify what the type is:

fn main() {
    let x = problem();
    println!("{}", x);
}

pub fn problem() -> i32 {
    let on_end = 13;
    on_end
}

Though this doesn't work for things like closures. There's an unstable feature in that for nightly, but it's unavailable in stable Rust.

Thanks, but you explicitly defined returned type. I am wondering is it possible to avoid that? What feature?

You can read the proposal for the feature I mentioned here:

https://rust-lang.github.io/rfcs/2515-type_alias_impl_trait.html

1 Like

So it's not possible?

I think it has already been discussed, but -> impl Trait is for "the function chooses what type to return" and a parameterized type is for "the caller chooses which type to get back".

Both have their uses but do different things, and both are in common use.

So we could explain how the parameterization works but it sounds like it's not useful for what you wanted to do with the question in the other topic.

1 Like

That looks like sugar.

Yes. Thanks, I understand the difference.

Good, so for your problem function to compile, the body of the function can only use features allowed by the trait bounds on that generic parameter. Unfortunately, assigning the value 13 is not allowed by any there. But if you had a trait bound like From<i32>, it could be, then you could call ThatType::from(13). That's just an example.

2 Likes

I am wondering if control of the type of returned value is something possible?

From<i32>

I have been thinking about that.

Control of the type is not possible, the caller chooses any type that fits the traits bounds, when using parameterization in that way.

1 Like

Control of the type is not possible, the caller chooses any type that fits the traits bounds, when using parameterization in that way.

Yes. I meant if control by caller is possible?
That code I demnstrated does not compile.

Ok, here's a working example.

use num_traits::Zero;

fn get_zero<T: Zero>() -> T { T::zero() }


let x = get_zero::<f64>();

The caller chooses to get the type f64.

1 Like

But if you had a trait bound like From<i32> , it could be, then you could call ThatType::from(13) . That's just an example.

How to reach that?

Interesting.

But if you had a trait bound like From<i32> , it could be, then you could call ThatType::from(13) . That's just an example.

I have reached the goal with Default trait. Is it possible to reach the goal with Into/From?


fn main() {
    let x = problem::<i32>();
    println!("{}", x);
    let x = problem::<i64>();
    println!("{}", x);
}

pub fn problem<T>() -> T
where
    T: Default,
{
    T::default()
}

use ::core::fmt::Display;

fn main ()
{
    let x = problem::<i32>();
    println!("{}", x);
    let x = problem::<i64>();
    println!("{}", x);
}

//

pub fn problem<ContainerEnd>() -> ContainerEnd
where
    ContainerEnd : Display, // Not necessary, but ok
 // ContainerEnd : From<u8>, /* slightly better than this: */
    u8 : Into<ContainerEnd>,
{
    let on_end = 13_u8;
    on_end.into()
}
3 Likes

@Yandros amazing! Thank you :smiley:

@Yandros but, why Rust compiler want to have u8 : Into<ContainerEnd> stated explicitly in where?

let on_end = 13_u8;

That implements trait Into. Is not that self-obvious fact?