FunLand.Reducible behaviour (fun_land v0.10.0)
Anything that implements the Reducible behaviour, can be reduced to a single value, when given a combinable (or combining-function + base value).
This is enough information to convert any reducible to a List. It even is enough information to implement most enumerable methods.
However, what is not possible, is to stop halfway through the reduction. Therefore, Reducible is a lot simpler than the Enumerable protocol.
For convenience, though, a very basic implementation of the Enumerable protocol is
automatically added when you use Reducible
. This implementation first converts your Reducible
to a list, and then enumerates on that.
This is very convenient, but it does mean that your whole reducible is first converted to a list. This will therefore always be slower than a full-blown custom implementation that is specific for your structure.
If you want to implement your own version of Enumerable, add Reducible with use FunLand.Reducible, auto_enumerable: false
.
Link to this section Summary
Functions
A variant of reduce that accepts anything that is Combinable as second argument. This Combinable will determine what the empty value and the combining operation will be.
Link to this section Types
reducible(a)
Specs
reducible(a) :: FunLand.adt(a)
Link to this section Functions
reduce(a, combinable)
A variant of reduce that accepts anything that is Combinable as second argument. This Combinable will determine what the empty value and the combining operation will be.
Pass in the combinable module name to start with empty
as accumulator,
or the combinable as struct to use that as starting accumulator.
This is an automatic function implementation, made possible because FunLand.Reducible
implements the FunLand.Reducible
behaviour.
Some examples:
iex> ["the", "quick", "brown", "fox"] |> FunLand.Reducible.reduce("")
"thequickbrownfox"
Or given the following module:
defmodule Score do
defstruct [val: 0]
use FunLand.Combinable
def new(val), do: %Score{val: val}
def empty(), do: new(0)
def combine(%Score{val: a}, %Score{val: b}), do: new(a + b)
end
iex> [Score.new(10), Score.new(20), Score.new(42)] |> FunLand.Reducible.reduce(Score)
%Score{val: 72}