Permalink
Browse files

Merge pull request #159 from emnl/List_Fold_Docs

Foldr & Foldl with docs
  • Loading branch information...
2 parents 241c86c + 270d09c commit 58d9b866f039c0c39158c64657cff1137f58e99c @josevalim josevalim committed Mar 6, 2012
Showing with 142 additions and 85 deletions.
  1. +130 −85 lib/list.ex
  2. +12 −0 test/elixir/list_test.exs
View
@@ -5,13 +5,16 @@ defmodule List do
# Bifs: member/2, reverse/2
# Bifs: keymember/3, keysearch/3, keyfind/3
- # Wraps the argument in a list.
- # If the argument is already a list, returns the list.
- # If the argument is nil, returns an empty list.
- #
- # ## Examples
- #
- # List.wrap [1,2,3] #=> [1,2,3]
+ @doc """
+ Wraps the argument in a list.
+ If the argument is already a list, returns the list.
+ If the argument is nil, returns an empty list.
+
+ ## Examples
+
+ List.wrap [1,2,3] #=> [1,2,3]
+
+ """
def wrap(list) when is_list(list) do
list
end
@@ -24,91 +27,129 @@ defmodule List do
[else]
end
- # Appends the list of lists all the given lists together.
- #
- # ## Examples
- #
- # List.append [[1,[2],3], [4], [5,6]]
- # #=> [1,[2],3,4,5,6]
- #
+ @doc """
+ Appends the list of lists all the given lists together.
+
+ ## Examples
+
+ List.append [[1,[2],3], [4], [5,6]]
+ #=> [1,[2],3,4,5,6]
+
+ """
def append(list) do
Erlang.lists.append(list)
end
- # Appends the list on the right to the list on the left.
- # If the list on the left contains only one element, the
- # we simply add it as a head as an optimization. This
- # function does the same as the `++` operator.
- #
- # ## Examples
- #
- # List.append [1,2,3], [4,5,6]
- # #=> [1,2,3,4,5,6]
- #
+ @doc """
+ Appends the list on the right to the list on the left.
+ If the list on the left contains only one element, the
+ we simply add it as a head as an optimization. This
+ function does the same as the `++` operator.
+
+ ## Examples
+
+ List.append [1,2,3], [4,5,6]
+ #=> [1,2,3,4,5,6]
+
+ """
def append(left, right) do
left ++ right
end
- # Flattens the given `list` of lists. An optional
- # tail can be given that will be added at the end of
- # the flattened list.
- #
- # ## Examples
- #
- # List.flatten [1,[[2],3]]
- # # => [1,2,3]
- #
- # List.flatten [1,[[2],3]], [4,5]
- # # => [1,2,3,4,5]
- #
+ @doc """
+ Flattens the given `list` of lists. An optional
+ tail can be given that will be added at the end of
+ the flattened list.
+
+ ## Examples
+
+ List.flatten [1,[[2],3]]
+ # => [1,2,3]
+
+ List.flatten [1,[[2],3]], [4,5]
+ # => [1,2,3,4,5]
+
+ """
def flatten(list, tail // []) when is_list(list) and is_list(tail) do
do_flatten(list, tail)
end
- # TODO: Write docs + tests
+ @doc """
+ Folds (reduces) the given list to the left with
+ a function. Requires an accumulator.
+
+ ## Examples
+
+ List.foldl [5,5], 10, fn(x, acc) -> x + acc end
+ #=> 20
+
+ List.foldl [1,2,3,4], 0, fn(x, acc) -> x - acc end
+ #=> 2
+
+ """
+ def foldl(list, acc, function) do
+ Erlang.lists.foldl(function, acc, list)
+ end
+
+ @doc """
+ Folds (reduces) the given list to the right with
+ a function. Requires an accumulator.
+
+ ## Examples
+
+ List.foldr [1,2,3,4], 0, fn(x, acc) -> x - acc end
+ #=> -2
+
+ """
def foldr(list, acc, function) do
Erlang.lists.foldr(function, acc, list)
end
- # Reverses the given list. This function simply delegates
- # to `lists:reverse` which is implemented in C for performance.
- #
- # ## Examples
- #
- # List.reverse [1,2,3]
- # #=> [3,2,1]
- #
+ @doc """
+ Reverses the given list. This function simply delegates
+ to `lists:reverse` which is implemented in C for performance.
+
+ ## Examples
+
+ List.reverse [1,2,3]
+ #=> [3,2,1]
+
+ """
defdelegate [reverse: 1], to: Erlang.lists
- # Checks if the given `term` is included in the list.
- # This function simply delegates to `lists:member`
- # which is implemented in C for performance.
- #
- # ## Examples
- #
- # List.member? [1,2,3], 1
- # #=> true
- #
- # List.member? [1,2,3], 0
- # #=> false
- #
+ @doc """
+ Checks if the given `term` is included in the list.
+ This function simply delegates to `lists:member`
+ which is implemented in C for performance.
+
+ ## Examples
+
+ List.member? [1,2,3], 1
+ #=> true
+
+ List.member? [1,2,3], 0
+ #=> false
+
+ """
def member?(list, term) when is_list(list) do
Erlang.lists.member(term, list)
end
- # Prepend the items given as first argument to list
- # as right argument. Note that items are prepended in
- # reverse order. This function does not modify the tail
- # and therefore does not duplicate the entries in memory.
- #
- # ## Examples
- #
- # List.prepend [1], [2, 3]
- # #=> [1,2,3]
- #
- # List.prepend [1,0], [2, 3]
- # #=> [0,1,2,3]
- #
+ @doc """
+ Prepend the items given as first argument to list
+ as right argument. Note that items are prepended in
+ reverse order. This function does not modify the tail
+ and therefore does not duplicate the entries in memory.
+
+ ## Examples
+
+ List.prepend [1], [2, 3]
+ #=> [1,2,3]
+
+ List.prepend [1,0], [2, 3]
+ #=> [0,1,2,3]
+
+ """
def prepend([h|t], other) do
prepend(t, [h|other])
end
@@ -117,25 +158,29 @@ defmodule List do
other
end
- # Returns a list as a sequence from first to last.
- # Returns an empty list if last is lower than first.
- #
- # ## Examples
- #
- # List.seq(1, 3) #=> [1,2,3]
- # List.seq(1, 1) #=> [1]
- #
+ @doc """
+ Returns a list as a sequence from first to last.
+ Returns an empty list if last is lower than first.
+
+ ## Examples
+
+ List.seq(1, 3) #=> [1,2,3]
+ List.seq(1, 1) #=> [1]
+
+ """
def seq(first, last) when is_integer(first) and is_integer(last) and first <= last + 1 do
do_seq(last - first + 1, last, [])
end
- # Returns a list without duplicated items.
- #
- # ## Examples
- #
- # List.uniq [1,2,3,2,1]
- # #=> [1,2,3]
- #
+ @doc """
+ Returns a list without duplicated items.
+
+ ## Examples
+
+ List.uniq [1,2,3,2,1]
+ #=> [1,2,3]
+
+ """
def uniq(list) when is_list(list) do
do_uniq(list, [])
end
@@ -28,6 +28,18 @@ defmodule ListTest do
assert_equal [1,2,3,4,5], List.flatten([[1,[2],3]], [4,5])
end
+ test :foldl do
+ assert_equal 6, List.foldl([1,2,3], 0, fn(x,y) -> x + y end)
+ assert_equal 16, List.foldl([1,2,3], 10, fn(x,y) -> x + y end)
+ assert_equal 2, List.foldl([1,2,3,4], 0, fn(x,y) -> x - y end)
+ end
+
+ test :foldr do
+ assert_equal 6, List.foldr([1,2,3], 0, fn(x,y) -> x + y end)
+ assert_equal 16, List.foldr([1,2,3], 10, fn(x,y) -> x + y end)
+ assert_equal -2, List.foldr([1,2,3,4], 0, fn(x,y) -> x - y end)
+ end
+
def test_member? do
assert List.member? [1,2,3], 1
refute List.member? [1,2,3], 0

0 comments on commit 58d9b86

Please sign in to comment.