 defmodule Dict do
   @moduledoc ~S"""
   This module specifies the Dict API expected to be
-  implemented by different dictionaries. It also provides
-  functions that redirect to the underlying Dict, allowing
-  a developer to work with different Dict implementations
-  using one API.
+  implemented by different dictionaries.
+
+  It also provides functions that redirect to the underlying
+  Dict, allowing a developer to work with different Dict
+  implementations using one API.
 
   To create a new dict, use the `new` functions defined
   by each dict type:

  Merges the dict `dict2` into dict `dict1`.

  If one of the `dict2` entries is found in `dict1`, the
  conflicting entries in `dict2` have higher precedence unless a
  function is given to resolve conflicts.

  Notice this function is polymorphic as it merges dicts of any
  type. Each dict implementation also provides a `merge` function,


  """
  @spec merge(t, t, (key, value, value -> value)) :: t
  def merge(dict1, dict2, fun) do
    target1 = target(dict1)
    target2 = target(dict2)

    if target1 == target2 do
      target1.merge(dict1, dict2, fun)
    else
      do_merge(target1, dict1, dict2, fun)
    end
  end

  defp do_merge(target1, dict1, dict2, fun) do
    Enumerable.reduce(dict2, {:cont, dict1}, fn({k, v}, acc) ->
      {:cont, target1.update(acc, k, v, fn(other) -> fun.(k, other, v) end)}
    end) |> elem(1)
  end

  @doc """
