Polymorphism in Elixir

Polymorphism is the provision of a single interface to entities of different types. Basically, it allows different data types respond to same function. So the same function shapes for different data types to accomplish the same behaviour. Elixir language has ‘protocols’ to implement polymorphism with a clean way.

Lets implement a basic protocol that convert Kelvin and Fahrenheit temperatures to Celsius.

`defmodule Kelvin do  defstruct name: "Kelvin", symbol: "K", degree: 0 end`
`defmodule Fahrenheit do  defstruct name: "Fahrenheit", symbol: "°F", degree: 0end`
`defmodule Celsius do  defstruct name: "Celsius", symbol: "°C", degree: 0end`
`defprotocol Temperature do  @doc """  Convert Kelvin and Fahrenheit to Celsius degree  """  def to_celsius(degree)end`
`defimpl Temperature, for: Kelvin do  @doc """  Deduct 273.15  """  def to_celsius(kelvin) do    celsius_degree = kelvin.degree - 273.15    %Celsius{degree: celsius_degree}  endend`
`defimpl Temperature, for: Fahrenheit do  @doc """  Deduct 32, then multiply by 5, then divide by 9  """  def to_celsius(fahrenheit) do    celsius_degree = (fahrenheit.degree - 32) * 5 / 9    %Celsius{degree: celsius_degree}  endend`

Now, we implemented our converters for the Kelvin and Fahrenheit types. Lets make some conversions:

`iex> fahrenheit = %Fahrenheit{degree: 45}%Fahrenheit{degree: 45, name: "Fahrenheit", symbol: "°F"}iex> celsius = Temperature.to_celsius(fahrenheit)%Celsius{degree: 7.22, name: "Celsius", symbol: "°C"}`
`iex> kelvin = %Kelvin{degree: 300}%Kelvin{degree: 300, name: "Kelvin", symbol: "K"}iex> celsius = Temperature.to_celsius(kelvin)%Celsius{degree: 26.85, name: "Celsius", symbol: "°C"}`

Lets try to convert any other data type which has no implementation for to_celsius function:

`iex> Temperature.to_celsius(%{degree: 12})** (Protocol.UndefinedError) protocol Temperature not implemented for %{degree: 12}    iex:11: Temperature.impl_for!/1    iex:15: Temperature.to_celsius/1`

If you want to cover all data types you can define an implementation for Any data type. Lastly, if you have time, check source code of Enum and String.Char’, which are good examples of polymorphism in core Elixir.

Happy functional coding with ♥!