原谅设计得很糟糕的伪代码,但我希望它能明白这一点:
float sqrt takes float n : [0,inf)
    // fancy algorithm
    return result
void main
    x = sqrt -1             // Compilation error
    y = sqrt float.max      // This works
    z = (y + 1) * (y + 1)   // Compilation error (this would result in overflow)
在编译期间,编译器分析sqrt函数并将其表征为
sqrt : [0,float.max] -> [0, sqrt float.max[
它通过对+, -, *, /操作员做同样的事情来做到这一点。
在main函数中,第一条语句不编译,因为sqrt不接受负输入。第三条语句无法编译,因为*运算符只接受会导致输出的输入[float.min, float.max]。