Someone once showed me a little 'trick' in SML where they wrote out about 3 or 4 functions in their REPL and the resulting type for the last value was extremely long (like many page scrolls long).
Does anyone know what code generates such a long type, or if there is a name for this kind of behavior?
Standard ML is a strongly and statically typed programming language. However, unlike many other strongly typed languages, the types of literals, values, expressions and functions in a program will be calculated by the Standard ML system when the program is compiled. This calculation of types is called type inference.
Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given.
Rust uses Hindley-Milner type inference. OCaml uses Hindley-Milner. Swift apparently uses a variant of the system with more features.
The types that are inferred by Hindley/Milner type inference can become exponentially large if you compose them in the right way. For example:
fun f x = (x, x, x) val t = f (f (f (f (f 0))))
Here, t
is a nested triple, whose nesting depth corresponds to the number n of invocations of f
. Consequently, the overall type has size 3^n.
However, this is not actually the worst case, since the type has a regular structure and can be represented by a graph efficiently in linear space (because on each level, all three constituent types are the same and can be shared).
The real worst case uses polymorphic instantiation to defeat this:
fun f x y z = (x, y, z) val p1 = (f, f, f) val p2 = (p1, p1, p1) val p3 = (p2, p2, p2)
In this case, the type is again exponentially large, but unlike above, all constituent types are different fresh type variables, so that even a graph representation grows exponentially (in the number of pN declarations).
So yes, Hindley/Milner-style type inference is worst-case exponential (in space and time). It is worth pointing out, however, that the exponential cases can only occur where types get exponentially large -- i.e. in cases, that you cannot even realistically express without type inference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With