How many design patterns are just a cope for your language not having sum types and pattern matching? That’s certainly true of, say, the visitor pattern. Maybe too strong a statement but I can’t say I’ve ever seen a design pattern be useful. Just write the code, in the simplest way you can. Try not to make the control flow jump around very much.
Haskell’s got both sum types and pattern matching and it still has the monad design pattern, so
Are monads a cope for your language not having an imperative programming style? (This is mostly a joke)
They’re a cope for not having continuations or effect handlers ;)
The visitor pattern in particular can still be useful in languages with sum types and pattern matching in cases where you have a deeply nested and recursive data type like an AST. For example say you want to rewrite some of the expressions; without an AST visitor you need to write tons of boring and error-prone pattern matching code. With a visitor object/struct you only need to override a single method/function.
Wouldn’t you need to write one function per AST node type in the effect class? How is that different from writing a big pattern match?
Yes, but you can write a mapper or folder visitor once and then reuse it multiple times.