let f = foobinade a b
in a curried language then you don't immediately know if `f` is the result of foobinading `a` and `b` or if `f` is `foobinade` partially applied to some of its arguments. Without currying you'd either write let f = foobinade(a, b)
or let f = foobinade(a, b, $) // (using the syntax in the blog post)
and now it's immediately explicitly clear which of the two cases we're in. type UserID = { readonly __tag: unique symbol }
Now clients of `UserID` no longer knows anything about the representation. Like with the original approach you need a bit of casting, but that can be neatly encapsulated as it would be in the original approach anyway.