Hi,
I am also think, that dependent/refinement types' purpose is to take a prove from a programmer, that one had checked once in runtime, that some variable satisfies some condition and then use that prove during compile time checks, thus eliminating requirement to use multiple runtime checks.
I think, that the example above is not too precise due to missing of context. Usually, you will have a function of type T -> bool to check condition in runtime, but dependent types allow you to encode property so it will be able to be checked in compile time.
Instead, I suggest to view an example of checking command line argument: say, that some app is able to handle arguments "add" and "delete", then you can code some property P_delete(x) and P_add(x), so that some function delete will be like:
fn {cmd: string | P_delete(s)} delete( s string cmd, ...) = ...
and
fn {cmd: string | P_add(s)} add( s: string cmd, ...) = ...
such that you:
1. have to check for content of string once in runtime - you are not required to actually check it contents in delete() and add();
2. be sure, that you haven't used delete() when command is not delete().
The interesting question is: is it possible to not define argument ```s``` for both of those functions at all, as we know it's content/property already.