Elixir Data Types — Integers, Floats, Atoms, Tuples, Lists, Maps
In this tutorial, you will learn about Elixir Data Types. We cover key concepts, practical examples, and best practices to help you master this topic.
Elixir is a dynamically-typed language with a rich set of built-in data types. Understanding these types — and how pattern matching interacts with them — is the foundation of writing idiomatic Elixir code.
In this tutorial, you'll explore every data type in Elixir. Elixir runs on the BEAM VM, which means its data structures are immutable and designed for concurrent access.
What You'll Learn
- Integers, floats, and numeric operations
- Atoms — Elixir's named constants
- Strings and charlists
- Tuples for fixed-size collections
- Lists for variable-size collections
- Maps and keyword lists
- Pattern matching with each type
Numbers
# Integers (arbitrary precision)
42
-17
1_000_000 # Underscores as separators
# Floats (IEEE 754 double)
3.14
-0.5
1.0e-10
# Integer division and remainder
div(10, 3) # => 3
rem(10, 3) # => 1
# Type checking
is_integer(42) # => true
is_float(3.14) # => true
is_number(42) # => true
is_number(3.14) # => true
Atoms
Atoms are constants whose name IS their value — similar to symbols in Ruby or enums in other languages:
:hello
:ok
:error
true # atom :true
false # atom :false
nil # atom :nil
# Atoms are used for status
case File.read("file.txt") do
{:ok, content} -> IO.puts(content)
{:error, reason} -> IO.puts("Error: #{reason}")
end
Strings
# Binaries (double-quoted)
name = "Elixir"
IO.puts("Hello, #{name}!") # Interpolation: "Hello, Elixir!"
# String operations
String.length("Hello") # => 5
String.upcase("hello") # => "HELLO"
String.contains?("Elixir", "ix") # => true
# Charlists (single-quoted, rare)
'hello'
Tuples
# Fixed-size, ordered collections
person = {"Alice", 30, "Engineer"}
# Access by index
elem(person, 0) # => "Alice"
elem(person, 1) # => 30
# Pattern matching on tuples
{name, age, role} = person
IO.puts(name) # => "Alice"
# Common pattern: {:ok, result} | {:error, reason}
{:ok, data} = File.read("exists.txt")
Lists
# Linked lists (variable size)
list = [1, 2, 3, 4]
# Head/tail pattern
[head | tail] = list
IO.puts(head) # => 1
IO.puts(tail) # => [2, 3, 4]
# Prepending (efficient)
new_list = [0 | list] # [0, 1, 2, 3, 4]
# List operations
length([1, 2, 3]) # => 3
[1, 2] ++ [3, 4] # => [1, 2, 3, 4]
[1, 2, 3] -- [2] # => [1, 3]
Enum.map([1, 2, 3], fn x -> x * 2 end) # => [2, 4, 6]
Maps
# Key-value store (efficient for lookup)
user = %{
name: "Alice",
age: 30,
skills: ["Elixir", "Erlang"]
}
# Access
user.name # => "Alice"
user[:name] # => "Alice"
Map.get(user, :name) # => "Alice"
Map.get(user, :city, "Unknown") # => "Unknown"
# Update (returns new map — immutability!)
updated = %{user | age: 31}
# Pattern matching on maps
%{name: n} = user
IO.puts(n) # => "Alice"
Keyword Lists
# Special form: list of 2-tuples with atom keys
options = [format: :json, pretty: true, depth: 2]
# Same as:
options = [{:format, :json}, {:pretty, true}, {:depth, 2}]
# Used for function options
IO.inspect("hello", label: "debug", width: 40)
# Access
options[:format] # => :json
Practice Questions
Create a map representing a book with title, author, year, and genres.
Write a function that accepts a tuple of
{:ok, value}or{:error, reason}and handles both cases.Use head/tail pattern matching to sum all elements in a list.
Convert a keyword list to a map using
Map.new/1.Write a pattern that extracts the first two elements and the rest from a list.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro