1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| defmodule CustomRange do
defstruct [:start, :stop]
end
defimpl Enumerable, for: CustomRange do
def count(%CustomRange{start: start, stop: stop}) do
{:ok, stop - start + 1}
end
def member?(%CustomRange{start: start, stop: stop}, value) do
{:ok, value >= start and value <= stop}
end
def reduce(%CustomRange{start: start, stop: stop}, acc, fun) do
reduce_range(start, stop, acc, fun)
end
defp reduce_range(current, stop, {:cont, acc}, fun) when current <= stop do
reduce_range(current + 1, stop, fun.(current, acc), fun)
end
defp reduce_range(_, _, {:halt, acc}, _fun), do: {:halted, acc}
defp reduce_range(_, _, {:suspend, acc}, fun), do: {:suspended, acc, &reduce_range(&1, &2, &3, fun)}
defp reduce_range(_, _, acc, _fun), do: {:done, acc}
def slice(_), do: {:error, __MODULE__}
end
# 使用
range = %CustomRange{start: 1, stop: 5}
Enum.to_list(range) # => [1, 2, 3, 4, 5]
|