Skip to content

Instantly share code, notes, and snippets.

@joeljuca
Created October 9, 2020 01:47
Show Gist options
  • Save joeljuca/2c73ab14701d6bf8c0d9808dc4bfd1dc to your computer and use it in GitHub Desktop.
Save joeljuca/2c73ab14701d6bf8c0d9808dc4bfd1dc to your computer and use it in GitHub Desktop.
defmodule ListOps do
# Please don't use any external modules (especially List or Enum) in your
# implementation. The point of this exercise is to create these basic
# functions yourself. You may use basic Kernel functions (like `Kernel.+/2`
# for adding numbers), but please do not use Kernel functions for Lists like
# `++`, `--`, `hd`, `tl`, `in`, and `length`.
@spec count(list) :: non_neg_integer
# def count(l), do: count(0, l)
# defp count(counter, []), do: counter
# defp count(counter, [_h | t]), do: count(counter + 1, t)
def count(l), do: reduce(l, 0, fn _x, acc -> acc + 1 end)
@spec reverse(list) :: list
def reverse(l), do: reverse(l, [])
defp reverse([], acc), do: acc
defp reverse([h | t], acc), do: reverse(t, [h | acc])
@spec map(list, (any -> any)) :: list
def map(l, f) do
for element <- l, do: f.(element)
end
@spec filter(list, (any -> as_boolean(term))) :: list
def filter(l, f) do
for n <- l, f.(n), do: n
end
@type acc :: any
@spec reduce(list, acc, (any, acc -> acc)) :: acc
def reduce([], acc, _f), do: acc
def reduce([head | tail], acc, f), do: reduce(tail, f.(head, acc), f)
@spec append(list, list) :: list
def append(a, b) do
reduce(reverse(a), b, fn item, acc -> [item | acc] end)
end
@spec concat([[any]]) :: [any]
# def concat(ll), do: reduce(reverse(ll), [], &append/2)
def concat([]), do: []
def concat([list, []]), do: list
def concat([list | tail]), do: append(list, concat(tail))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment