Elixir Language
El polimorfismo en el elixir
Buscar..
Introducción
El polimorfismo es la provisión de una interfaz única para entidades de diferentes tipos. Básicamente, permite que diferentes tipos de datos respondan a la misma función. Entonces, la misma función da forma a diferentes tipos de datos para lograr el mismo comportamiento. El lenguaje elixir tiene protocols para implementar el polimorfismo de una manera limpia.
Observaciones
Si desea cubrir todos los tipos de datos, puede definir una implementación para Any tipo de datos. Por último, si tiene tiempo, verifique el código fuente de Enum y String.Char , que son buenos ejemplos de polimorfismo en el núcleo Elixir.
Polimorfismo con Protocolos
Implementemos un protocolo básico que convierta las temperaturas de Kelvin y Fahrenheit a Celsius.
defmodule Kelvin do
defstruct name: "Kelvin", symbol: "K", degree: 0
end
defmodule Fahrenheit do
defstruct name: "Fahrenheit", symbol: "°F", degree: 0
end
defmodule Celsius do
defstruct name: "Celsius", symbol: "°C", degree: 0
end
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}
end
end
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}
end
end
Ahora, implementamos nuestros convertidores para los tipos Kelvin y Fahrenheit. Hagamos algunas conversiones:
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"}
Intentemos convertir cualquier otro tipo de datos que no tenga implementación para la función to_celsius :
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