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