Records are everywhere in Elm. Your first Model in Elm (or maybe your second) was a record. We use them to hold data of various other types together in one structure. They are a bit like objects in javascript. You can define a record with multiple fields of different types, and then use them elsewhere, e.g. in a list.

type alias User =

{ id : Int

, name : String

, age : Int

} type alias UserList = List User

Records have limitations too. You cannot iterate or map over the fields in a record. To the frequent frustration of those coming from javascript (like me), Elm has no record[key] to dynamically access fields. In Elm (like in javascript), the fields in a record can be of any type (which is 👍). But dynamic typing would break the type safety guarantee of the Elm compiler.

Fortunately, there is plenty of other goodness in Elm Records. Here’s a couple of lesser known features of Records, that you may find useful.

#1. Free functions

Records come with free functions too. Let’s examine the following User record:

type alias User =

{ id : String

, name : String

, age : Int

}

The basic features are that you can get the name of a user like this:

someName = someUser.name

And you can create an updated user with a new name and age like this:

newUser =

{ oldUser

| name = newName

, age = newAge

}

Free with your records

But there is more! With the User record defined as a type alias, you also get the following functions for free:

User : String -> String -> Int -> User

.id : User -> String

.name : User -> String

.age : User -> Int

The capitalized function User is a constructor. You can use it to construct a User by supplying all fields as arguments. In a previous post, you can find more detail on using constructors.

The other free functions are getter functions. That’s right, these functions begin with a . (dot).

Let’s look at a practical use case: Let’s say you have a List of User s, and you want to have only the names of these users. With the free dot-function, all you need is this:

userNames = List.map .name users