Haskell have a garbage collector (and it have a lot or work to do). So even if you are in the context of immutability, if you don't want a gc, you still need to take care of memory yourself using RAII like Rust or any other low level technique. About syntax for me haskell is beautiful. But maybe it's just my love for having type notation aside from function declaration and not mixed.
Garbage collectors can really be very efficient in languages that are both strongly-typed and truly immutable.
The type system means you don't have to worry about folks hiding pointers in arbitrary pointer-sized integers, so you know all the roots ahead of time.
Immutability means you can only ever create references in one direction (i.e from new objects to old objects), and you can't ever create cycles.
This lets you do fun shit like a mark&sweep garbage collector in a single pass (rather than the usual two) - and if you have process isolation guarantees (a la Erlang), you don't necessarily have to suspend execution while it runs. Or maybe a generational collector where the generations are entirely implicit.
The GC could be very smart and optimized, but at the end... "Any sufficiently complicated program in a garbage-collected language contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of malloc and free". https://news.ycombinator.com/item?id=22802451