What do you mean "a zero value would be impossible"? The whole idea is that sometimes you need it, and sometimes you don't, so you want your language to let you distinguish these 2 cases and then check for your program's exhaustiveness in checking it when you do have a zero value.
The fact dereferences are checked converts one runtime error into another. Proper sum types convert a runtime error into a compile-time error. How do you possibly view this as "most of the same benefits"?
3. No, they allow you to use the wrong value when there actually was an error and the value has a different meaning than intended (or just another nil dereference).
The type system forces you to have either error checking or you can use explicit type system escape hatches which are then greppable. For example, Haskell does have unsafe functions like "fromJust" which unsafely assume a result value is not an error -- but these functions are rightly considered a code smell. If you want to use them, you can, at least making the smelly parts of the code easily findable. In Go, all the code is smelly, instead.
4. Type switch statements are so clunky I don't think they can, with a straight face, be considered "effective" alternatives for pattern matching.
Consider:
myFunction Nothing = ...
myFunction (Just x) = ...
This is understandable. This is effective. Do you think the equivalent type switch in Go is?Type systems don't become cages and aren't "crutches". They are tools that you can use as much as you want. A program in Haskell can be written to be type-unsafe and put all the code in useless types. Or it can encode any amount from very little to a lot in the type system. It's just a tool you get to choose how much of your invariants you want to verify.
Go doesn't offer you that tool.