Skip to content

Instantly share code, notes, and snippets.

Avatar

Adam Lancaster Adzz

View GitHub Profile
@Adzz
Adzz / bad_behaviours.ex
Created Nov 15, 2021
This is a gist that demos what behaviours and protocols look like in Elixir. Used as part of onboarding
View bad_behaviours.ex
defmodule Shape do
@callback area(map()) :: integer()
@callback perimeter(map()) :: integer()
end
defmodule Square do
defstruct [:side]
@behaviour Shape
@Adzz
Adzz / koppel_to_do.ex
Last active Sep 15, 2019
Your task is to design the data layer for a to-do list app. Create the core data structures that track state, along with an API that can be connected to any frontend
View koppel_to_do.ex
# Third round of feature requests
# Extend your design to support one of the following two features:
# Ability to look up, for all users, how many have a todo item with the same name as one of yours.
# Also, explain how to extend your user interface to display the total number of todo items in the
# list currently being viewed. This feature is simple, but there are some easy ways to get it wrong.
# Ability to go back into the past, and see what a user's todo list looked like at any point in time.
# Explain how this would work for todo lists that already exist.
# =================================================================================================
View typing_functions.go
// As you might expect
func add(x int, y int) int {
return x + y
}
// Go functions can return multiple values though, so you
// Can type each of the return values
func swap(x, y string) (string, string) {
return y, x
}
View zip_blog_post_8.ex
map_1 = %{first: 1, second: 2}
map_2 = %{first: 3, second: 4}
# These just work! 🤩
Zip.apply(map_1, map_2, Add) #=> %{first: 4, second: 6}
Zip.apply(map_1, map_2, Subtract) #=> %{first: 4, second: 6}
View zip_blog_post_7.ex
defimpl Zip, for: Map do
def apply(a, b, operation) do
# We take the all the keys from b that are also in a
intersection = Map.take(b, Map.keys(a))
Enum.reduce(a, %{}, fn {key, value}, acc ->
Map.put(acc, key, operation.calculate(value, Map.fetch!(intersection, key)))
end)
end
end
View zip_blog_post_6.ex
defprotocol Subtract do
def calculate(a, b)
end
# And implement it
defimpl Subtract, for: Integer do
def calculate(a, b) when is_integer(b), do: a - b
end
defimpl Subtract, for: Decimal do
View zip_blog_post_5.ex
defimpl Add, for: Decimal do
def calculate(decimal, decimal_2 = %Decimal{}), do: Decimal.add(decimal, decimal_2)
end
list_1 = [Decimal.new(1), Decimal.new(2)]
list_2 = [Decimal.new(3), Decimal.new(4)]
Zip.apply(list_1, list_2, Add) #=> [Decimal.new(4), Decimal.new(6)]
View zip_blog_post_4.ex
defimpl Zip, for: List do
def apply(a, b, operation) do
Enum.zip(a, b)
|> Enum.map(fn {a, b} -> operation.calculate(a, b) end)
end
end
# Now we can call it like this:
Zip.apply([1, 2], [3, 4], Add) #=> [4, 6]
View zip_blog_post_3.ex
defprotocol Add do
def calculate(a, b)
end
# Now we can define implementations of it for the various kinds of
# data types we might get inside our collections that we are zipping.
defimpl Add, for: Integer do
def calculate(a, b) when is_integer(b), do: a + b
end
View zip_blog_post_2.ex
defprotocol Zip do
def apply(collection_1, collection_2, operation)
end
# We can implement it for lists:
defimpl Zip, for: List do
def apply(a, b, calculate) do
Enum.zip(a, b)
|> Enum.map(fn {a, b} -> calculate.(a, b) end)
end