This is not a practical application, I just want to know whether Rust could acheive this or not. I think it can be done in physics, but not sure whether it violates Rust's type system.
I tried using a helper trait but failed.
trait SelfFn: (Fn() -> Self) + 'static {}
impl<T> SelfFn for T where T: (Fn() -> Self) + 'static {}
fn a() -> impl SelfFn {
a
}
it doesn't compiles
error[E0275]: overflow evaluating the requirement `<fn() -> impl SelfFn {a} as FnOnce<()>>::Output == fn() -> impl SelfFn {a}`
--> src/lib.rs:4:11
|
4 | fn a() -> impl SelfFn {
| ^^^^^^^^^^^
|
note: required for `fn() -> impl SelfFn {a}` to implement `SelfFn`
--> src/lib.rs:2:9
|
2 | impl<T> SelfFn for T where T: (Fn() -> Self) + 'static {}
| ^^^^^^ ^ ---- unsatisfied trait bound introduced here
For more information about this error, try `rustc --explain E0275`.
I suspect this is impossible without adding another level of indirection.
If you were to remove the impl SelfFn and write out the actual type being returned, what would you put in there? You'd say that a returns a function that returns a function that returns a function that returns a... Ad infinitum.
It's kinda like when a type contains itself, so the compiler can't figure out how big it'll be. A trivial example is when you try to define a node in a linked list:
I got your point, thanks, but your workaround doesn't completely match the question. The final structure or function is required to implements Fn() -> Self, so that it can be called like this:
func()()()().....()();
but yours will be look like:
func.call().call().call()......call().call();
And, with an extra Box layer, it caused an extra allocation overhead.
If so, obviously we have a better and widely used solution, the builder pattern.
State S0, Input 1
Next state will be S1
State S1, Input 0
Next state will be S2
State S2, Input 0
Next state will be S1
State S1, Input 1
Next state will be S0