Skip to content

Instantly share code, notes, and snippets.

@amacgregor
Created January 17, 2016 19:37
Show Gist options
  • Save amacgregor/ab9d8fa74708543e065a to your computer and use it in GitHub Desktop.
Save amacgregor/ab9d8fa74708543e065a to your computer and use it in GitHub Desktop.
defmodule ListOps do
# Please don't use any external modules (especially List) in your
# implementation. The point of this exercise is to create these basic functions
# yourself.
#
# Note that `++` is a function from an external module (Kernel, which is
# automatically imported) and so shouldn't be used either.
@doc """
Sums all the values inside the provided list
"""
@spec count(list) :: non_neg_integer
def count([]), do: 0
def count([_|tail]) do
count(tail) + 1
end
@doc """
Take a list and return the a new list with the elements in reverse order
"""
@spec reverse(list) :: list
def reverse(list), do: _reverse(list,[])
defp _reverse([],l), do: l
defp _reverse([h|t],l), do: _reverse(t, [h|l])
@doc """
Take a list and an anonymous function and run the anonymous function on each eklement of the list
"""
@spec map(list, (any -> any)) :: list
def map([],f), do: []
def map([h|t],f), do: [f.(h) | map(t,f)]
@doc """
Takes two argumets a list and an anonymous function, then runs the anonymous functions against each element of the list
the list must return a boolean value
"""
@spec filter(list, (any -> as_boolean(term))) :: list
def filter(list, f), do: _filter(list, f, [])
defp _filter([], f, l), do: reverse(l)
defp _filter([h|t], f, l) do
if f.(h) do
l = [h|l]
end
_filter(t, f, l)
end
@doc """
Reduce implementation, it applies a function against and accumulator and each value of the provided list
"""
@type acc :: any
@spec reduce(list, acc, ((any, acc) -> acc)) :: acc
def reduce([], acc, f), do: acc
def reduce([h|t], acc, f), do: reduce(t, f.(h, acc), f)
@doc """
Append a list at the end of another list
"""
@spec append(list, list) :: list
def append(a, b), do: _append(reverse(a), b)
defp _append([], b), do: b
defp _append([h|t], b), do: _append(t, [h|b])
@doc """
Concatenate a series of list together in a single larger list
"""
@spec concat([[any]]) :: [any]
def concat(lists), do: _concat(reverse(lists), [])
defp _concat([], l), do: l
defp _concat([h|t], l), do: _concat(t, append(h,l))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment