Nevermind, I kept researching, and while I didn't find the same exact 
proposal, I did encounter things down the rabbit hole that changed my mind.

I think Andrea's criticism of 
short_maps(https://andrealeopardi.com/posts/a-story-of-regret-and-retiring-a-library-from-hex/#why-i-don-t-like-short-maps)
 
applies here too. Gonna shortcut the year of learning, accept his wisdom, 
and withdraw.

On Tuesday, July 25, 2023 at 6:23:35 PM UTC-4 Joe Martinez wrote:

> I have a feeling there's probably a better way to do this, but I couldn't 
> find it in the history.
>
> This would let you do something like this:
> iex> users = [%{name: "john", age: 27, employment: %{title: "Developer", 
> salary: 100}}, %{name: "meg", age: 23, employment: %{title: "Manager", 
> salary: 200}}]
> iex> get_in(users, [Access.all(), Access.keys([:name, employment: 
> [:title]])])
> [%{employment: %{title: "Developer"}, name: "john"}, %{name: "meg", 
> employment: %{title: "Manager"}}]
>
> With keys partially implemented like this
> def keys(keys) do
>   fn
>     :get, data, next ->
>       next.(take(data, keys))
>
>     :get_and_update, data, next ->
>       values = take(data, keys)
>
>       case next.(values) do
>         {values, :pop} -> {values, Map.drop(data, keys)}
>         {values, updates} -> {values, updates}
>       end
>   end
> end
>
> And then that `take` function something like this:
> @doc """
> ## Examples
>     iex> Access.take(%{name: "john", age: 52}, [:name, :age, :height])
>     %{name: "john", age: 52}
>
>     iex> Access.take(%{name: "john", age: 52, employment: %{title: 
> "Developer", salary: 100}}, [:name, :height, employment: [:title]])
>     %{name: "john", employment: %{title: "Developer"}}
> """
> def take(container, keys) when is_list(keys) do
>   cond do
>     Enum.all?(keys, &is_atom/1) and is_map(container) ->
>       Map.take(container, keys)
>
>     is_map(container) ->
>       keys
>       |> Enum.group_by(&is_atom/1)
>       |> Enum.reduce(%{}, fn
>         {true, keys}, map ->
>           Map.merge(map, Map.take(container, keys))
>
>         {false, pairs}, map ->
>           Map.merge(
>             map,
>             for({k, v} <- pairs, into: %{}, do: {k, 
> take(Map.get(container, k), v)})
>           )
>       end)
>   end
> end
>
> def take(_container, keys) when is_list(keys) do
>   raise ArgumentError, "Access.take expects the keys to be a list of atoms 
> or keyword list, got: " <> inspect(keys)
> end
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/560b0f5c-997e-4e78-bfb6-b2019457ea14n%40googlegroups.com.

Reply via email to