list_ops.exs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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.

  @spec count(list) :: non_neg_integer
  def count([]), do: 0
  def count([_ | tail]), do: 1 + count(tail)


  @spec reverse(list) :: list
  defp acc_reverse([], acc), do: acc
  defp acc_reverse([head | tail], acc), do: acc_reverse(tail, [head | acc])
  def reverse(l), do: acc_reverse(l, [])


  @spec map(list, (any -> any)) :: list
  def map([], _f), do: []
  def map([head | tail], f), do: [f.(head) | map(tail, f)]


  @spec filter(list, (any -> as_boolean(term))) :: list
  def filter([], _f), do: []
  def filter([head | tail], f) do
    if f.(head) do
      [head | filter(tail, f)]
    else
      filter(tail, f)
    end
  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([], []), do: []
  def append([], [head | tail]), do: [head | tail]
  def append([head | tail], l), do: [head | append(tail, l)]


  @spec concat([[any]]) :: [any]
  def concat([]), do: []
  def concat([head_list | tail]), do: append(head_list, concat(tail))
end

Comments

Because it takes a different number of arguments you could just change the name of acc_reverse/2 to reverse/2 and it will still work. You defined acc_reverse twice so you probably knew you could do this--did you have a reason for wanting to call it something different?

smcabrera commented 15 July 2016 at 22:00 UTC

You're not logged in right now. Please login via GitHub to comment