Skip to content

Instantly share code, notes, and snippets.

@duksis
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duksis/5338e6f7bd285ba2c0a2 to your computer and use it in GitHub Desktop.
Save duksis/5338e6f7bd285ba2c0a2 to your computer and use it in GitHub Desktop.
Elixir deep_foldl
# # https://gist.github.com/ashneyderman/5c88439c68b19ecf50d5
# @type reducer :: (term, term -> term)
# @spec deep_foldl(list, term, reducer) :: term
#
# ## deep folds should accept arbitrarily deep nested lists
# ## it should call the fun on anything which is not a list.
# ## For a flat list, it should do the same thing as erlang's
# ## lists:foldl/3.
#
# 15 = deep_foldl([[1,[2,[3,[4,5]]]]], 0, fn(N,Sum) -> N+Sum end).
#
# %% Can you make it tail recursive?
ExUnit.start
defmodule DeepFoldlTest do
use ExUnit.Case, async: true
@type reducer :: (term, term -> term)
@spec deep_foldl(list, term, reducer) :: term
defp deep_foldl([], acc, _) do acc end
defp deep_foldl([head | tail], acc, fun) when is_list(head) do
deep_foldl(head ++ tail, acc, fun)
end
defp deep_foldl([head | tail], acc, fun) do
deep_foldl(tail, fun.(head, acc), fun)
end
test "acceptance" do
assert 15 == deep_foldl([[1,[2,[3,[4,5]]]]], 0, &+/2)
end
#test "nested multi element list" do
# assert 6 = deep_foldl([1,[2,3]], 0, &+/2)
#end
#test "first element nested list" do
# assert 3 = deep_foldl([[1],2], 0, &+/2)
#end
#test "empty list" do
# assert 3 == deep_foldl([], 3, &+/2)
#end
#test "simple list of integers" do
# assert 3 = deep_foldl([1,2], 0, &+/2)
#end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment