Skip to content

Instantly share code, notes, and snippets.

View Adzz's full-sized avatar

Adam Lancaster Adzz

View GitHub Profile
@Adzz
Adzz / triple.ex
Last active November 28, 2018 16:05
defmodule AmazeOn do
defstruct [price: 10]
end
defmodule Area do
defstruct []
end
defmodule Square do
defstruct [:side]
@Adzz
Adzz / ecto_morph.ex
Last active April 14, 2019 19:52
Ecto Morph blog post
response = %{"meat_type" => "medium rare", "pickles" => false, "collection_date" => "2019-11-04"}
# We want a struct so that we can do things like implement protocols for it
defmodule SteamedHam do
defstruct [:meat_type, :pickles, :collection_date]
end
# With no !, the struct function selects only the fields defined in the schema.
steamed_ham = struct(SteamedHam, response)
defmodule Test do
def thing() do
1+1
end
defmacro my_macro do
quote do
1 + 1
end
end
list_1 = [1, 2]
list_2 = [3, 4]
Zip.apply(list_1, list_2, fn x, y -> x + y end) #=> [4, 6]
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
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
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]
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)]
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
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