Interesting question!
While there are many structures for which an 'empty' might make sense,
there are some (probably more) for which it does not. To be more formal
about this: `Collectable` is essentially an implementation of what is known
as a `SemiGroup` in Category Theory terms (pedantically speaking, it
implements the concatenation function ('Collectable.into') directly rather
than having a binary combining operator that the concatenation function is
built on top of).
If you have a SemiGroup that happens to also have a well-defined
empty/default value, we end up with what is known as a `Monoid`.
While Elixir does not have a protocol or behaviour in place to work with
things that are Monoids directly, there are still two ways you can make it
work:
1. By allowing the user to provide the desired 'default' data structure
directly (rather than the module it is defined in). This is what we already
do when writing `into: %{}` for instance. The nice thing about this
approach is that it allows the user to specify *any* data structure, not
only empty ones. (There are many data structures for which there is more
than one reasonable default, and there are also cases in which the user
might want to collect multiple enumerables in the same collection. Both of
these use cases are covered by this).
2. If you happen to write something where it is difficult for the user to
provide a datastructure and they only give you a module atom, you can still
look if the module has a `new/0` method: While not standardized, this is a
convention which a very large amount of libraries as well as Elixir's
standard library seem to follow.
~Qqwy/Marten
On Tuesday, May 21, 2019 at 5:46:29 PM UTC+2, Benjamin Milde 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/e98aeb01-b04b-4f0f-acec-bbf24fb95b88%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.