# Elm Friday: Type Annotations (Part VI)

11/27/15

One of Elm’s most important characteristics is its static type system. This enables Elm to make much stronger guarantees during run time compared to dynamic languages like JavaScript. This boils down to “If it compiles, it’ll never throw a runtime exception”. In this episode, we’ll look into the type system and on *type annotations* in particular more closely.

## About This Series

This is the sixth post in a series of short and sweet blog posts about Elm. The stated goal of this series is to take you from “completely clueless about Elm” to “chief Elm guru”, step by step. If you have missed the previous episodes, you might want to check out the table of contents.

## Type Annotations Versus Type Inference

Although Elm is a statically typed language, our examples in the previous posts had no type declarations whatsoever. The reason is that Elm can infer the type of almost any expression. That means that everything is typed, either explicitly by adding a *type annotation* or implicitly by relying on Elm’s type inference.

Let’s revisit some of the functions from the last episode and add type annotations to them. The type annotations are the line just before the function definition:

import Html multiply : number -> number -> number multiply a b = a * b square : number -> number square a = multiply a a productOfSquares : number -> number -> number productOfSquares a b = multiply (square a) (square b) incrementAll : List number -> List number incrementAll list = List.map (\ n -> n + 1) list incrementAll2 : List number -> List number incrementAll2 = List.map (\ n -> n + 1) main : Html.Html main = let print n = Html.text <| toString n in Html.p [] [ print <| multiply 3 5 , Html.br [] [] , print <| square 4 , Html.br [] [] , print <| productOfSquares 2 3 , Html.br [] [] , print <| incrementAll [1, 2, 3] , Html.br [] [] , print <| incrementAll2 [1, 2, 3] ]

(Remark: I refactored the main function a bit from the last episode by extracting the duplicated conversion from number/list into an HTML text element.)

To pick one example, `square : number -> number`

is the type annotation for the function definition of `square`

. A type annotation should be written directly in the line above the function definition. It is comprised of the function name, a colon, and the types of all input parameters and the return type, each separated by `->`

.

There is no distinction between a parameter type and the return type. Coming from other languages, you might expect that the type annotation for `multiply`

somehow makes it clear that two numbers go *in* and one number comes *out*. For example the type signature could read `(number, number) -> number`

. It doesn't. The separator between the first and second input parameter is `->`

, just as the separator between the second input parameter and the return type. This is because talking about first and second input parameter is just *one* way of thinking about `multiply`

. You could also say that `multiply`

takes only one parameter and returns a *function with the signature number -> number*. Both are equally valid points of view. You can either think of this function as

`(number, number) -> number`

or `number -> (number -> number)`

. The reason is that Elm supports currying and partial function application naturally.Here is a code example that illustrates this:

import Htmlmultiply : number -> number -> number

multiply a b = a * bmultiplyByFive : number -> number

multiplyByFive = multiply 5-- The expression (multiply 5) yields a new function with signature

-- (number -> number) by partial appication, that is: the first argument to

-- multiply is provided, but not the second.main : Html.Html

main = multiplyByFive 3 |> toString |> Html.text

## Comment