   end
 
   defp typespec({:%{}, meta, fields} = map, vars, caller) do
-    map_fun = fn
-      {k, v} when is_atom(k) ->
-        args = [typespec(k, vars, caller), typespec(v, vars, caller)]
-        {:type, line(meta), :map_field_exact, args}
-
-      {{:required, meta2, [k]}, v} ->
-        args = [typespec(k, vars, caller), typespec(v, vars, caller)]
-        {:type, line(meta2), :map_field_exact, args}
-
-      {{:optional, meta2, [k]}, v} ->
-        args = [typespec(k, vars, caller), typespec(v, vars, caller)]
-        {:type, line(meta2), :map_field_assoc, args}
-
-      {k, v} ->
-        # TODO: Warn on Elixir v1.8 (since v1.6 is the first version to drop support for 18 and
-        # older)
-        # warning =
-        #   "invalid map specification. %{foo => bar} is deprecated in favor of " <>
-        #   "%{required(foo) => bar} and %{optional(foo) => bar}."
-        # :elixir_errors.warn(caller.line, caller.file, warning)
-        args = [typespec(k, vars, caller), typespec(v, vars, caller)]
-        {:type, line(meta), :map_field_assoc, args}
-
-      {:|, _, [_, _]} ->
-        error =
-          "invalid map specification. When using the | operator in the map key, " <>
-            "make sure to wrap the key type in parentheses: #{Macro.to_string(map)}"
-
-        compile_error(caller, error)
-
-      _ ->
-        compile_error(caller, "invalid map specification: #{Macro.to_string(map)}")
-    end
-
-    fields = :lists.map(map_fun, fields)
+    fields =
+      Enum.map(fields, fn
+        {k, v} when is_atom(k) ->
+          args = [typespec(k, vars, caller), typespec(v, vars, caller)]
+          {:type, line(meta), :map_field_exact, args}
+
+        {{:required, meta2, [k]}, v} ->
+          args = [typespec(k, vars, caller), typespec(v, vars, caller)]
+          {:type, line(meta2), :map_field_exact, args}
+
+        {{:optional, meta2, [k]}, v} ->
+          args = [typespec(k, vars, caller), typespec(v, vars, caller)]
+          {:type, line(meta2), :map_field_assoc, args}
+
+        {k, v} ->
+          # TODO: Warn on Elixir v1.8 (since v1.6 is the first version to drop support for 18 and
+          # older)
+          # warning =
+          #   "invalid map specification. %{foo => bar} is deprecated in favor of " <>
+          #   "%{required(foo) => bar} and %{optional(foo) => bar}."
+          # :elixir_errors.warn(caller.line, caller.file, warning)
+          args = [typespec(k, vars, caller), typespec(v, vars, caller)]
+          {:type, line(meta), :map_field_assoc, args}
+
+        {:|, _, [_, _]} ->
+          error =
+            "invalid map specification. When using the | operator in the map key, " <>
+              "make sure to wrap the key type in parentheses: #{Macro.to_string(map)}"
+
+          compile_error(caller, error)
+
+        _ ->
+          compile_error(caller, "invalid map specification: #{Macro.to_string(map)}")
+      end)
+
     {:type, line(meta), :map, fields}
   end
 

  @spec defines_callback?(module, atom, arity) :: boolean
  def defines_callback?(module, name, arity)
      when is_atom(module) and is_atom(name) and arity in 0..255 do
    finder = fn {_kind, expr, _caller} ->
      spec_to_signature(expr) == {name, arity}
    end

    :lists.any(finder, Module.get_attribute(module, :callback))
  end

  @doc """

  end

  defp typespec(list, vars, caller) when is_list(list) do
    [head | tail] = Enum.reverse(list)

    union =
      Enum.reduce(tail, validate_kw(head, list, caller), fn elem, acc ->
        {:|, [], [validate_kw(elem, list, caller), acc]}
      end)

    typespec({:list, [], [union]}, vars, caller)
  end

