Manuel Albarran

A random notes about Elixir

Polymorphism (Part 0) - Bare Elixir - Pattern Matching

18 Feb 2017 » elixir, polymorphism

The definition of circularity, corresponding to that of parameter K defined by Cox, is given as follows:1

The following is a very basic implementation of cicularity without protocols or behaviors for Circle, Square, and Rectangle.

defmodule Circle, do: defstruct [:r]
defmodule Square, do: defstruct [:a]
defmodule Rectangle, do: defstruct [:w, :h]

defmodule Polygon do
  @doc "Calculates the area of a polygon"
  def area(%Circle{r: r}), do: :math.pi * r * r
  def area(%Square{a: a}), do: a * a
  def area(%Rectangle{w: w, h: h}), do: w * h

  @doc "Calculates the perimeter of a polygon"
  def perimeter(%Circle{r: r}), do: 2 * :math.pi * r
  def perimeter(%Square{a: a}), do: 4 * a
  def perimeter(%Rectangle{w: w, h: h}), do: 2 * w + 2 * h

  def circularity(polygon) do
    area = polygon |> area
    perimeter = polygon |> perimeter 

    (4 * :math.pi * area) / (perimeter * perimeter)
  end
end

%Circle{r: 10} |> Polygon.area
#> 304.0592653589793
%Circle{r: 10} |> Polygon.circularity
#> 1.0 # A Perfect Circle

%Square{a: 10} |> Polygon.area
#> 100
%Square{a: 10} |> Polygon.circularity
#> 0.7853980633974483

%Rectangle{w: 10, h: 5} |> Polygon.area
#> 50
%Rectangle{w: 10, h: 5} |> Polygon.circularity
#> 0.6981317007977318

[%Circle{r: 10}, %Square{a: 10}, %Rectangle{w: 10, h: 5} ] |> Enum.each(fn polygon ->
  IO.puts polygon |> Polygon.area
  IO.puts polygon |> Polygon.perimeter
  IO.puts polygon |> Polygon.circularity
end)
#> 314.1592653589793
#> 62.83185307179586
#> 1.0
#> 100
#> 40
#> 0.7853981633974483
#> 50
#> 30
#> 0.6981317007977318