Hello. I want to implement a fixed point for generic data type as below:
pub enum Fun<T> {
Cons(Box<T>),
// blablablabla
}
// want to pass Self as generic parameter
type FunSelf = Fun<FunSelf>;
// FunSelf would be become this after monomorphization
pub enum FunSelf {
Cons(Box<FunSelf>),
// blablablabla
}
// but that doesn't check
// though I can write this
struct FunSelf(Fun<FunSelf>);
// it seems weird and it brings unbearable noisy in my code
How do I approximately implement it without too many nested structs in Rust?
From what I can tell, recursive types cannot be achieved by anything other than struct or enum. The same issue is present in other languages as well, see Recursive data type, section In type synonyms in Wikipedia.
It might be more favorable for you to state the demanded type this way:
Perhaps not really answering your question, but it might be of interest: Your question made attempt to adapt the examples in the explanation of a generic Fix data type from Haskell
newtype Fix f = Fix (f (Fix f))
that can be found in this answer on SO
into Rust.
(Using an approach of Functors in Rust adapting my own earlier toy example for Monads:)
One thing I noticed was the need to add a layer of indirection in defining Fix
struct Fix<F: TyCon>(Rc<F::Of<Fix<F>>>);
// would work with `Box`, too
// using `Rc` everywhere for making adapting code
// from a pure functional language easier
otherwise, the compiler isn’t happy because F::Of<A> might contain an A without indirection and there isn’t a good way to restrict a GAT to disallow this. (The “not good” way I’ve found would be to require that F::Of<A> is supposed to support unsized A while being Sized itself, but that’s way stronger of a requirement than necessary.)