3 ms·
my best guess is that you can't do recursive enums without explicit boxing [edit: or other forms of indirection, like &T]¹. so you can't do this: enum List<
by uryga 7y ago
my best guess is that you can't do recursive enums without explicit boxing [edit: or other forms of indirection,
like &T]¹. so you can't do this:
enum List<T> {
Nil,
Cons(T, List<T>)
}
instead, you have to box/reference-ify the recursive occurrence:
enum List<T> {
Nil,
Cons(T, Box<List<T>>)
}
so in certain circumstances it doesn't let you "coproduct" two types together, you might need to modify one a bit, which makes it a technically-not-exactly-a-coproduct (i think). a bit of a stretch but it sort of makes sense next to a by-reference-only ML langs where you can (co)product anything as you please
(btw, it's the same for recursive products)
---
1 - https://users.rust-lang.org/t/recursive-enum-types/2938/2 https://users.rust-lang.org/t/recursive-enum-types/2938/2
- Ygg2 7y agoI think that's because Rust types are Sized, but I could be wrong. The first example has size = Infinity, while the second has a constant size.
- leshow 7y agoThanks for commenting, that's probably it. I was aware of the requirement for explicit box-ing but it didn't immediately come to mind.
- steveklabnik 7y agoYou don't have to box, but you do need some sort of type to make things sized. This is usually a pointer of some kind, but any kind of pointer works. Take references, for example: enum List<'a, T> { Nil, Cons(T, &'a List<'a, T>) } fn main() { let list = List::Cons("hello", &List::Nil); } Box is usually chosen because it's a good default choice.
- uryga 7y agoyou're right of course! i should've used a more generic term like "indirection" or "reference", didn't mean to put emphasis on Box
- steveklabnik 7y agoIt’s all good, most people say just Box, because it is the majority case.