Witchcraft v1.0.0-beta.2 Witchcraft.Foldable View Source

Data that can be folded over to change its structure by altering or combining elements

Examples

iex> right_fold([1, 2, 3], 0, &+/2) # sum
6

Properties

People are working on Foldable properties. This is one of the exceptions to there needing to conform to properties. In the meantime, we are testing that naturality is preserved, which is be a free theorm.

If that fails, something is very wrong with the instance.

Type Class

An instance of Witchcraft.Foldable define Witchcraft.Foldable.right_fold/3.

Foldable   [right_fold/3]

Link to this section Summary

Functions

Check if a foldable is full of only trues

The same as all?/1, but with a custom predicate matcher

Check if a foldable contains any trues

The same as all?/1, but with a custom predicate matcher

Concatenate all lists in a foldable structure

Lift a function over a foldable structure generating lists of results, and then concatenate the resulting lists

Check if a foldable data structure is empty

Combine all elements using monoidal append

Map a functional over all elements and fold them together

The same as left_fold/3, but uses the first element as the seed

Left-associative fold over a structure to alter the structure and/or reduce it to a single summary value

Count the number of elements in a foldable structure

Find the maximum element in a foldable structure using the default ordering from Witchcraft.Ord

Find the maximum element in a foldable structure using a custom comparitor

Check if a foldable structure contains a particular element

Find the minimum element in a foldable structure using the default ordering from Witchcraft.Ord

Find the maximum element in a foldable structure using a custom comparitor

Test whether the structure is empty. The default implementation is optimized for structures that are similar to lists, because there is no general way to do better

Product of all numbers in a foldable

The same as right_fold/3, but uses the first element as the seed

Right-associative fold over a structure to alter the structure and/or reduce it to a single summary value. The right-association makes it possible to cease computation on infinite streams of data

Sum all numbers in a foldable

Run each action from left to right, discarding all values

Turn any Foldable into a List

Link to this section Types

Link to this section Functions

Link to this function all?(foldable_bools) View Source
all?(Witchcraft.Foldable.t) :: boolean

Check if a foldable is full of only trues

Examples

iex> all?([true, true, false])
false

%BinaryTree{
  left:  true,
  right: %BinaryTree{
    left:  true,
    right: false
  }
} |> all?()
#=> false
Link to this function all?(foldable, predicate) View Source
all?(Witchcraft.Foldable.t, (any -> boolean)) :: boolean

The same as all?/1, but with a custom predicate matcher

Examples

iex> import Integer
...> all?([1, 2, 3], &is_odd/1)
false

%BinaryTree{
  left:  1,
  right: %BinaryTree{
    left:  2,
    right: 3
  }
}
|> all?(&Integer.is_odd?/1)
#=> false
Link to this function any?(foldable_bools) View Source
any?(Witchcraft.Foldable.t) :: boolean

Check if a foldable contains any trues

Examples

iex> any? [true, true, false]
true

%BinaryTree{
  left:  true,
  right: %BinaryTree{
    left:  true,
    right: false
  }
} |> any?()
#=> true
Link to this function any?(foldable, predicate) View Source
any?(Witchcraft.Foldable.t, (any -> boolean)) :: boolean

The same as all?/1, but with a custom predicate matcher

Examples

iex> require Integer
...> any?([1, 2, 3], &Integer.is_odd/1)
true

%BinaryTree{
  left:  1,
  right: %BinaryTree{
    left:  2,
    right: 3
  }
}
|> any(&Integer.is_odd?/1)
#=> true
Link to this function concat(contained_lists) View Source
concat(Witchcraft.Foldable.t) :: [any]

Concatenate all lists in a foldable structure

Examples

iex> concat([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
[1, 2, 3, 4, 5, 6, 7, 8, 9]

%BinaryTree{
  left:  [1, 2, 3],
  right: %BinaryTree{
    left:  [4, 5],
    right: [6]
  }
}
|> concat()
#=> [1, 2, 3, 4, 5, 6]
Link to this function concat_map(foldable, mapper) View Source
concat_map(Witchcraft.Foldable.t, (any -> [any])) :: [any]

Lift a function over a foldable structure generating lists of results, and then concatenate the resulting lists

Examples

iex> concat_map([1, 2, 3, 4, 5, 6], fn x -> [x, x] end)
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6]

%BinaryTree{
  left:  1,
  right: %BinaryTree{
    left:  2,
    right: 3
  }
}
|> concat_map(fn x -> [x, x] end)
#=> [1, 1, 2, 2, 3, 3]

Check if a foldable data structure is empty

Examples

iex> empty?("")
true

iex> empty?("hi")
false

iex> empty?(%{})
true

Combine all elements using monoidal append

Examples

iex> fold([1, 2, 3])
6

iex> fold([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Link to this function fold_map(foldable, fun) View Source
fold_map(Witchcraft.Foldable.t, (... -> any)) :: any

Map a functional over all elements and fold them together

Examples

iex> fold_map([1, 2, 3], fn x -> [x, x * 10] end)
[1, 10, 2, 20, 3, 30]

iex> fold_map([[1, 2, 3], [4, 5, 6], [7, 8, 9]], fn x -> [x, x] end)
[
  [1, 2, 3], [1, 2, 3],
  [4, 5, 6], [4, 5, 6],
  [7, 8, 9], [7, 8, 9]
]
Link to this function left_fold(foldable, folder) View Source

The same as left_fold/3, but uses the first element as the seed

Examples

iex> left_fold([1, 2, 3], &+/2)
6

iex> left_fold([100, 2, 5], &//2)
10.0 # ((100 / 2) / 5)

iex> left_fold([1 | [2 | [3]]], fn(x, acc) -> [x | acc] end)
[[1 | 2] | 3]
Link to this function left_fold(foldable, seed, folder) View Source

Left-associative fold over a structure to alter the structure and/or reduce it to a single summary value.

The folder must be a binary function, with the second argument being the accumulated value thus far.

Examples

iex> sum = fn xs -> right_fold(xs, 0, &+/2) end
...> sum.([1, 2, 3])
6
...> sum.([4, 5, 6])
15

iex> left_fold([1, 2, 3], [], fn(x, acc) -> [x | acc] end)
[[[[] | 1] | 2] | 3]
Link to this function length(list) View Source
length(Witchcraft.Foldable.t) :: non_neg_integer

Count the number of elements in a foldable structure

Examples

iex> use Witchcraft.Foldable
...> length(%{})
0
iex> length(%{a: 1, b: 2})
2
iex> length("ࠀabc")
4

Find the maximum element in a foldable structure using the default ordering from Witchcraft.Ord.

Elements must implement Witchcraft.Ord.

Examples

iex> use Witchcraft.Foldable
...> max([2, 3, 1])
3
...> max([[4], [1, 2, 3, 4]])
[4]

%BinaryTree{
  node: 1,
  left: %BinaryTree{
    node: 3
    left: 4
  },
  right: 2
}
|> max()
#=> 4
Link to this function max(foldable, list) View Source
max(Witchcraft.Foldable.t, [{:by, (any, any -> Order.ordering)}]) :: Witchcraft.Ord.t

Find the maximum element in a foldable structure using a custom comparitor

Elements must implement Witchcraft.Ord.

Comes in both a safe and unsafe(!) version

Examples

iex> use Witchcraft.Foldable
...> [1, 2, 7]
...> |> max(by: fn(x, y) ->
...>   x
...>   |> Integer.mod(3)
...>   |> Witchcraft.Ord.compare(Integer.mod(y, 3))
...> end)
2
Link to this function member?(foldable, target) View Source
member?(Witchcraft.Foldable.t, any) :: boolean

Check if a foldable structure contains a particular element

Examples

iex> member?([1, 2, 3], 2)
true

iex> member?([1, 2, 3], 99)
false

iex> member?(%{a: 1, b: 2}, 2)
false

iex> member?(%{a: 1, b: 2}, {:b, 2})
true

Find the minimum element in a foldable structure using the default ordering from Witchcraft.Ord.

Elements must implement Witchcraft.Ord.

Examples

iex> use Witchcraft.Foldable
...> min([2, 3, 1])
1
...> min([[4], [1, 2, 3, 4]])
[1, 2, 3, 4]

%BinaryTree{
  node: 4,
  left: %BinaryTree{
    node: 3
    left: 1
  },
  right: 2
}
|> min()
#=> 1
Link to this function min(foldable, list) View Source
min(Witchcraft.Foldable.t, [{:by, (any, any -> Order.t)}]) ::
  any |
  Maybe.t

Find the maximum element in a foldable structure using a custom comparitor

Elements must implement Witchcraft.Ord.

Comes in both a safe and unsafe(!) version

Examples

iex> use Witchcraft.Foldable
...> [8, 2, 1]
...> |> min(by: fn(x, y) ->
...>   x
...>   |> Integer.mod(4)
...>   |> Witchcraft.Ord.compare(Integer.mod(y, 4))
...> end)
8

Test whether the structure is empty. The default implementation is optimized for structures that are similar to lists, because there is no general way to do better.

Examples

iex> null?([])
true

iex> null?([1, 2, 3])
false

Product of all numbers in a foldable

Examples

iex> product([1, 2, 3])
6

%BinaryTree{
  left:  4,
  right: %BinaryTree{
    left: 2,
    right: 10
  }
}
|> product()
#=> 80
Link to this function right_fold(foldable, folder) View Source
right_fold(Witchcraft.Foldable.t, (... -> any)) :: any

The same as right_fold/3, but uses the first element as the seed

Examples

iex> right_fold([1, 2, 3], &+/2)
6

iex> right_fold([100, 2, 5], &//2)
40.0 # (2 / (5 / 100))

iex> right_fold([[], 1, 2, 3], fn(x, acc) -> [x | acc] end)
[1, 2, 3]
Link to this function right_fold(foldable, seed, folder) View Source
right_fold(Witchcraft.Foldable.t, any, (any, any -> any)) :: any

Right-associative fold over a structure to alter the structure and/or reduce it to a single summary value. The right-association makes it possible to cease computation on infinite streams of data.

The folder must be a binary function, with the second argument being the accumulated value thus far.

Examples

iex> sum = fn xs -> right_fold(xs, 0, &+/2) end
...> sum.([1, 2, 3])
6
...> sum.([4, 5, 6])
15

Sum all numbers in a foldable

Examples

iex> sum([1, 2, 3])
6

%BinaryTree{
  left:  4,
  right: %BinaryTree{
    left: 2,
    right: 10
  }
} |> sum()
#=> 16

Run each action from left to right, discarding all values.

Always returns %Witchcraft.Unit{} in the same foldbale structure that you started with.

Examples

iex> then_sequence([[1, 2, 3], [4, 5, 6]])
[
  %Witchcraft.Unit{},
  %Witchcraft.Unit{},
  %Witchcraft.Unit{},
  %Witchcraft.Unit{},
  %Witchcraft.Unit{},
  %Witchcraft.Unit{},
  %Witchcraft.Unit{},
  %Witchcraft.Unit{},
  %Witchcraft.Unit{}
]

Turn any Foldable into a List

Example

iex> to_list({1, 2, 3})
[1, 2, 3]

iex> to_list(%{a: 1, b: 2, c: 3})
[c: 3, b: 2, a: 1]