Skip to content
Elixir

Protocols and Enums

Polymorphism via protocols and the Enum module.

By EZ4Code Team
protocolenumpolymorphism

Code

# Define a protocol
defprotocol Size do
  @doc "Calculate size"
  def size(data)
end

# Implement for List
defimpl Size, for: List do
  def size(list), do: length(list)
end

# Implement for Map
defimpl Size, for: Map do
  def size(map), do: map_size(map)
end

# Implement for String
defimpl Size, for: BitString do
  def size(str), do: String.length(str)
end

# Usage
Size.size([1, 2, 3])      # 3
Size.size(%{a: 1, b: 2})  # 2
Size.size("hello")        # 5

# Enum works on anything implementing Enumerable
Enum.map([1, 2, 3], fn x -> x * 2 end)   # [2, 4, 6]
Enum.map(%{a: 1, b: 2}, fn {k, v} -> {k, v * 2} end)  # [a: 2, b: 4]
Enum.sum(1..100)  # 5050

# Stream (lazy)
1..1000
|> Stream.map(fn x -> x * x end)
|> Stream.filter(fn x -> rem(x, 2) == 0 end)
|> Enum.take(5)  # [4, 16, 36, 64, 100]

Explanation

Protocols dispatch based on the data type — like interfaces in OOP but more flexible (you can implement for any type, including built-ins). Enum operates on any Enumerable (lists, maps, ranges). Stream is the lazy version — pipes compose without intermediate lists, useful for large/infinite collections. Use Enum for small data, Stream for pipelines.

More Elixir Snippets