I tried to translate the article to Rust, but seems that the article's gotcha in Haskell is not necessarily an issue in Rust if we return `dyn OurTrait`, so now I'm even more confused. If anyone could take a look what I'm missing that would be welcome:
------------
Say, you want to write a simple language interpreter.
You have an `Expr` enum (sum type), with say, a `Constant(f64)` and a `BinaryPlus(Expression, Expression)`.
You can easily add a new function expecting an `Expr` indeed, but if you were to add a new variant to the `Expr` enum, you would have to go through the code and change every use site.
You can solve the issue by simply making a `struct Constant` and a `struct BinaryPlus`. Now you can just define a new trait for both of them, and you can use that `dyn trait` in your code -- you can add new functions and also new types without code change at use site!
So what's the issue?
In Haskell, a logic like
```
func example(runtime_val: f64) -> Expr {
if (runtime_val is someRuntimeCheck())
return Constant(..)
else
return BinaryPlus(.., ..)
}```
can't compile in itself as `Expr` is a type class (=trait). Basically, in this mode Haskell awaits a concrete implementation (we actually get the exact same behavior with `impl Expr` in Rust), but here is my confusion: this can be circumvented in Rust with dyn traits..
Here is my (very ugly due to just hacking something together while pleasing the borrow checker) code showing it in Rust: https://play.rust-lang.org/?version=stable&mode=debug&editio...
Your confusion is my confusion: Rust supports this.