Function basics

Functions are the bread and butter of a language like Elm. A function takes one or more arguments as input, and does some calculations with them to return a new value.

Believe it or not, you've already used some functions. When we talked about Strings, we went over the toString function. It takes any type of value as an argument and returns a String.

> toString 42
"42"
> toString [ 1, 2, 3 ]
"[1,2,3]" : String

When we talked about Booleans, we went over the not function. It takes a Bool as an argument and returns its opposite.

> not True
False : Bool
> not (20 < 5)
True : Bool

Notice how we coerce the compiler into reading that expression 20 < 5 as a single argument by putting it in parentheses. In some languages, you need to use parentheses each time you call a function, but Elm only requires them in cases like this.

Reading functions' type signatures

Functions have type signatures just like any other value. You can get a function's type signature by entering it into the REPL with no arguments. Let's try this with not.

> not
<function: not> : Bool -> Bool

That arrow tells us that not takes a Bool and returns a Bool. We already knew that, but this is a quick and easy way to figure out how to use a function if you're not sure. A function's type signature tells you concisely the types of values it takes as arguments and returns.

Let's look at the type signature of toString:

> toString
<function> : a -> String

As you can see, type variables can appear in a function's type signature, too. This a is a concise way of telling us toString can take a value of any type.

Getting functions from a module

To see some more exciting functions, you'll have to import a module. Let's import the String module in the REPL so we can access some useful functions for working with Strings.

> import String

Now we can access all the functions in the String module. One of these is String.toUpper. Let's see what it does.

> String.toUpper
<function: toUpper> : String -> String

From the type signature of this function, we can tell it takes a String as its argument and returns a new String.

So if we try it out, there are no surprises:

> String.toUpper "Howdy!"
"HOWDY!" : String

You can import any of the modules in the Elm core package from the REPL.

Functions that take multiple arguments

Functions that take more than one argument aren't very different from single-argument functions. Just separate the arguments with spaces.

One easy-to-understand example is String.repeat. It takes two arguments: an Int and a String. Let's see what happens when we call this function.

> String.repeat 3 "ha"
"hahaha" : String
> String.repeat 5 "ho"
"hohohohoho" : String

As you can tell, it returns a new String made by repeating the argument String the same number of times as the Int.

String.split returns a List of Strings. It also takes two Strings as arguments.

> String.split "-" "do-re-mi"
["do","re","mi"] : List String
> String.split "h" "ahohohooo"
["a", "o", "o", "ooo"] : List String

When a function takes multiple arguments, its type signature looks a little different. Every argument type is followed by an -> arrow, and the return type comes last, as usual.

> String.repeat
<function: repeat> : Int -> String -> String
> String.split
<function: split> : String -> String -> List String

results matching ""

    No results matching ""