Using Head and Tail to Build a List

Let’s get more ambitious. Let’s write a function that takes a list of numbers and returns a new list containing the square of each. We don’t show it, but these definitions are also inside the MyList module.

lists/mylist1.exs
 def​ square([]), ​do​: []
 def​ square([ head | tail ]), ​do​: [ head*head | square(tail) ]

There’s a lot going on here. First, look at the parameter patterns for the two definitions of square. The first matches an empty list and the second matches all other lists.

Second, look at the body of the second definition:

 def​ square([ head | tail ]), ​do​: [ head*head | square(tail) ]

When we match a nonempty list, we return a new list whose head is the square of the original list’s head and whose tail is a list of squares of the tail. This is the recursive step.

Let’s try it:

 iex>​ c ​"​​mylist1.exs"
 [MyList]
 iex>​ MyList.square [] ​# this calls the 1st definition
 []
 iex>​ MyList.square [4,5,6] ​# and this calls the 2nd
 [16, 25, 36]

Let’s do something similar—a function that adds 1 to every element in the list:

lists/mylist1.exs
 def​ add_1([]), ​do​: []
 def​ add_1([ head | tail ]), ​do​: [ head+1 | add_1(tail) ]

And call it:

 iex>​ c ​"​​mylist1.exs"
 [MyList]
 iex>​ MyList.add_1 [1000]
 [1001]
 iex>​ MyList.add_1 [4,6,8]
 [5, 7, 9]