Протокол (Protocol.UndefinedError) Enumerable не реализован для 3

Я пытаюсь вернуть суммированную сумму после понимания. Вот что я пытаюсь:

range = 1..999

multiple_of_3_or_5? = fn(n) -> (rem(n, 3) == 0 || rem(n, 5) == 0) end
for n <- range, multiple_of_3_or_5?.(n),
  do: Enum.reduce(n, 0, fn(x, y) -> (x + y) end)

Кажется, что он должен суммировать список, возвращаемый из понимания, но вместо этого он печатает эту ошибку:

#=> ** (Protocol.UndefinedError) protocol Enumerable not implemented for 3

Может кто-нибудь помочь с этим?


person Bitwise    schedule 23.06.2017    source источник


Ответы (1)


Вы передаете каждое целое число для уменьшения вместо отфильтрованного списка. Вы должны передать результат for в Enum.reduce/3:

iex(1)> range = 1..999
1..999
iex(2)> multiple_of_3_or_5? = fn(n) -> (rem(n, 3) == 0 || rem(n, 5) == 0) end
#Function<6.118419387/1 in :erl_eval.expr/5>
iex(3)> for(n <- range, multiple_of_3_or_5?.(n), do: n) |> Enum.reduce(0, fn(x, y) -> (x + y) end)
233168

Вы также можете использовать Enum.sum/1, чтобы сократить это:

iex(4)> Enum.sum for n <- range, multiple_of_3_or_5?.(n), do: n
233168
person Dogbert    schedule 23.06.2017