Comment by qsera
8 hours ago
>you would have to change the code at all call sites.
Actually I think you can just change concrete argument `Foo` to type constraint in Haskell as well using a type class. So the function would be something like `foo :: ToMaybeFoo a => a -> .. ->`. And you would implment `ToMaybeFoo` instance for `Foo` and `Maybe Foo`.
Agree that this is more involved than typescript, but you get to keep `null` away from your code...
This is a neat idea, but it does require that you know up front the largest union that could ever be supported in that argument, so that you have the ability to narrow it down later. Worse, it in the limit it requires a combinatorial explosion of type classes, with one for each possible union! The `ToXYZorW` classes form a powerset over the available types.
See fundeps.
Admittedly I don't really understand your construction. But this solution, if it works, doesn't look practical enough that it could be routinely used in practice like Foo|Null could be. By the way, some languages even shorten "Foo|Null" to "Foo?" as syntax sugar.
> but you get to keep `null` away from your code...
I don't think this would be desirable once we have eliminated null pointer exceptions with untagged unions.
>Admittedly I don't really understand your construction.
It is quite simple. Instead of accepting a concrete type `Foo`, the function is changed to accept types that can be converted to `Option<Foo>`. Since both `Foo` and `Option<Foo>` can be converted to `Option<Foo>`, the existing call sites that passes `Foo` would not require changing.
https://play.haskell.org/saved/g4idq2zv