I've had quite often needs for doing some computation (mapping) on ecto result, but having a flexible function similar to `Repo.preload` currently needs a whole bunch of boilerplate in terms of differenciating collections from single items and especially returning the same type afterwards (e.g. keep it a collection or single item). I know that Enumerable and Collectable were split consciously, but it would be great to have something like `Collectable.empty/1`, so one could do some work using `Enum` functions and in the end do: `Enum.into(changed, Collectable.empty(initial))` and it would empty the collectable and fill it up again using the changed data. This way the `Repo.preload` could e.g. additionally support custom enumerable and collectable collections as first argument like e.g. `%Scrivener.Page{}`.
--
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-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/19c24b83-fc2a-4af3-950e-eba7f767db14%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
My concern is that Collectable.empty cannot be implemented by all structs. For example, what does it mean to call empty() on a IO.stream? Perhaps it would make sense as a separate protocol?Also, can you please expand on how Repo.preload could use Scrivener.Page in detail? Thanks!
On Tue, May 21, 2019 at 5:46 PM Benjamin Milde <lostko...@gmail.com> wrote:
I've had quite often needs for doing some computation (mapping) on ecto result, but having a flexible function similar to `Repo.preload` currently needs a whole bunch of boilerplate in terms of differenciating collections from single items and especially returning the same type afterwards (e.g. keep it a collection or single item). I know that Enumerable and Collectable were split consciously, but it would be great to have something like `Collectable.empty/1`, so one could do some work using `Enum` functions and in the end do: `Enum.into(changed, Collectable.empty(initial))` and it would empty the collectable and fill it up again using the changed data. This way the `Repo.preload` could e.g. additionally support custom enumerable and collectable collections as first argument like e.g. `%Scrivener.Page{}`.--
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-l...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/1498525e-30fd-4cde-92a0-4b2e01cdbdf3%40googlegroups.com.
--
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-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/e98aeb01-b04b-4f0f-acec-bbf24fb95b88%40googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/5dff9895-1921-4794-89b9-d4ff45578880%40googlegroups.com.
It should basically „reset“ the part of the struct, which is used by the Enumerable protocol implementation.
def empty(page), do: %{page | elements: []}
So that after an Enum.into(changes, SomeProtocol.empty(initial_page)) we end up with exactly the same metadata, but different elements.
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-core/3iBUmpKIYr8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Kueg013YTHmg7jS5o94Qb0YbEjOWRNbKuENKgPiMJK0g%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/DEDD7A1D-7CBD-4EC9-82B0-2C597DC8CC85%40kobrakai.de.
I’m actually with you that a different protocol is probably better.
This is basically what I added to my codebase over the duration of the conversion here.
Ecto could then decide to add support for such collections whenever it wants.
defprotocol Emptyable do
def empty(type)
end
defimpl Emptyable, for: List do
def empty(_), do: []
end
defimpl Emptyable, for: Map do
def empty(_), do: %{}
end
defimpl Emptyable, for: Scrivener.Page do
def empty(page), do: %{page | elements: []}
end
defmodule MyApp.Collection do
def with_items(collection, function) do
collection
|> Enum.to_list()
|> function.()
|> Enum.into(Emptyable.empty(collection))
end
def map(collection, mapper) do
with_items(collection, &Enum.map(&1, mapper))
end
def intersperse(collection, element) do
with_items(collection, &Enum.intersperse(&1, element))
end
def zip(collection, enumerable) do
with_items(collection, &Enum.zip(&1, enumerable))
end
def at(collection, index) do
with_items(collection, &Enum.at(&1, index))
end
def preload(collection, preloads, opts \\ []) do
with_items(collection, &MyApp.Repo.preload(&1, preloads, opts))
end
end
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Jc4E-1K7mXR1JCf_Z6_0rUo7UY7vQbPtB9Fs6bO-fnAA%40mail.gmail.com.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/5dff9895-1921-4794-89b9-d4ff45578880%40googlegroups.com.