A common example is validation/result types, which often look like string (error message) or valid result. So e.g. you might have a username validator that returns Result<String, String> and then various other user creation validation things that return e.g. Result<String, EmailAddress> and in the end you compose them all together to get Result<String, User>. That's a very powerful style that has the advantages of exceptions (the "happy path" through the code is obvious and not obscured by all the failure handling) without their disadvantages ("magic" control flow, seemingly trivial refactors changing the behaviour). But it's less practical if you can't have Result<String, String> at the base level.
They're a super good idea, so I'm glad that other languages are adopting it, but this is the kind of thing that haskell has had for a long time and is just second nature.
I suppose you meant to say "algebraic data types"? (which have been adopted by Rust and Swift, and even the C++ stdlib)