Created
November 15, 2021 15:45
-
-
Save Adzz/36a65d1dcb31a5db8ab8d231dce27bf4 to your computer and use it in GitHub Desktop.
This is a gist that demos what behaviours and protocols look like in Elixir. Used as part of onboarding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Shape do | |
@callback area(map()) :: integer() | |
@callback perimeter(map()) :: integer() | |
end | |
defmodule Square do | |
defstruct [:side] | |
@behaviour Shape | |
@impl Shape | |
def area(square) do | |
square.side * square.side | |
end | |
@impl Shape | |
def perimeter(square) do | |
square.side * 4 | |
end | |
end | |
defmodule Circle do | |
defstruct [:radius] | |
@behaviour Shape | |
@impl Shape | |
def area(circle) do | |
3.14 * circle.radius * circle.radius | |
end | |
@impl Shape | |
def perimeter(circle) do | |
circle.radius * 3.14 * 2 | |
end | |
end | |
square = %Square{side: 10} | |
circle = %Circle{radius: 10} | |
Square.area() | |
Circle.area() | |
defmodule Triangle do | |
defstruct [:base, :height] | |
end | |
defmodule ShapeHelpers do | |
def area(%{__struct__: shape_module} = shape) do | |
shape_module.area(shape) | |
end | |
end | |
ShapeHelpers.area(%Triangle{base: 1, height: 15}) | |
defprotocol Shape do | |
def area(shape) | |
def perimeter(shape) | |
end | |
defimpl Shape, for: Square do | |
def area(square) do | |
square.side * square.side | |
end | |
def perimeter(square) do | |
square.side * 4 | |
end | |
end | |
defimpl Shape, for: Cirle do | |
def area(circle) do | |
3.14 * circle.radius * circle.radius | |
end | |
def perimeter(circle) do | |
circle.radius * 3.14 * 2 | |
end | |
end | |
defmodule Square do | |
defstruct [:side] | |
end | |
Shape.area(%Square{side: 10}) | |
Shape.perimeter(%Circle{radius: 10}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment