Hacker News new | ask | show | jobs
by leshow 2427 days ago
What's "almost" algebraic about enum? It can definitely be used to construct sum types, and you can make product types with struct or inline in an enum
1 comments

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

You 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.
you're right of course! i should've used a more generic term like "indirection" or "reference", didn't mean to put emphasis on Box
It’s all good, most people say just Box, because it is the majority case.
I 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.
Thanks for commenting, that's probably it. I was aware of the requirement for explicit box-ing but it didn't immediately come to mind.