# Type Inference

The only required type annotated happens at the top-level module function and method level. The type-checker can infer most of the types at the local level.

Here is a simple example to show you the power of the type-inference algorithm:

The type checker can correctly deduce the type of lambda `(a, b, c) -> if a(b + 1) then b else c`

must be `((int) -> bool, int, int) -> int`

.

The type-checker first decides that `b`

must be `int`

since `+`

adds up two `int`

s. Then it knows
that `c`

must also be `int`

, because `b`

and `c`

must have the same type. From the syntax, `a`

must
be a function. Since the function application of `a`

happens at the boolean expression part of `if`

,
we know it must return `bool`

. Since `a`

accepts one argument that is `int`

, the type of `a`

must be
`(int) -> bool`

.

Although the type-checker is smart, in some cases it simply cannot determine the type because there is not enough information.

class NotEnoughTypeInfo {function <T> randomFunction(): T = panic("I can be any type!")function main(): unit = { val _ = randomFunction(); }}

The type of `randomFunction()`

cannot be decided. We decide not to make it generic because we want
every expression to have a concrete type. In this case, the type checker will instantiate the
generic type `T`

as `unit`

.