To achieve this I can implement Collectable for all my structs needing it.
defmodule Collstruct do
defmacro __using__(fields) do
quote do
defstruct unquote(fields)
defimpl Collectable, for: __MODULE__ do
def into(options) do
{ options, fn
acc, {:cont, {k, v}} -> Map.put(acc, k, v) # Some clever checks might go here
acc, :done -> acc
_, :halt -> :ok
end
}
end
end
end
end
end
I somehow fail to remember the reasoning why structs do not implement Collectable, maybe something to do with the some clever checks above?
Thank you.
I do have difficulties to conceptionally distinguish Structs from Maps. I will have an eye on that.
Kernel.struct/2 does exactly what I need for now. Please note though that it does the same as Enum.into. If you care to discuss the conceptional choices, why would one expose Kernel.struct/2 instead of keeping structs collectables?
Maps and structs share structure (you can pattern match on both equally), they do not share behaviour (protocols).
Structs need to have a clean slate so you can customize their behaviour. If Enum.into/2 was implemented for structs, everyone would use Enum.into/2 to change structs and when they come across a struct that implements Enum.into/2 to get a different behaviour, such as MapSet, they would get confusing results.