Haskell Description
Each expression in Haskell is assigned a type at compile time. All types that are combined by function application must match. The compiler will reject the program if they don't match up. Types are not only a guarantee, but also a language to express the construction of programs. Haskell functions are mathematical functions (i.e. "pure") in every instance. Even side-effecting IO operation are just a description of what to accomplish, and are produced by pure code. There are no instructions or statements, only expressions that can't mutate variables (local and global) or access state such as time or random numbers. You don't need to write every type in Haskell programs. Types can be inferred by unifying each type bidirectionally. You can however write out types or ask the compiler for them to be written for you.