'self recursive function type in rust [duplicate]

just curiosity: In python

def f(x):
    print(x)
    return f

but I can't figure out how to write it in rust.

fn f(x:i32) -> ?{
    println!("{}", x);
    ?
}


Solution 1:[1]

I don't believe you can do it with just an fn item.

Both fn f(x: i32) -> fn() -> ... and fn f(x: i32) -> impl Fn() -> ... aren't useful here, because you can't name the return type of the return type.

Trying to define a type alias type F = fn(i32) -> F also doesn't solve the problem, as it leads to a cycle error, and you can't use Self in type aliases.

I believe the only way is to use nightly-only features to implement the Fn trait of families for a struct, thus being able to name it when implementing Fn:

#![feature(unboxed_closures, fn_traits)]

struct F;

impl FnOnce<(i32,)> for F {
    type Output = F;
    extern "rust-call" fn call_once(self, args: (i32,)) -> Self::Output {
        self.call(args)
    }
}

impl FnMut<(i32,)> for F {
    extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> Self::Output {
        self.call(args)
    }
}

impl Fn<(i32,)> for F {
    extern "rust-call" fn call(&self, (x,): (i32,)) -> Self::Output {
        println!("{}", x);
        Self
    }
}

Playground

Downside with this problem is that you can't really get a fn(i32) -> Self, only a fn(i32) -> F, and you can't make F "implement" fn(i32) -> F, as it's not a trait.

All this said, this is probably a bad idea and only really useful for curiosity's sake

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Filipe Rodrigues