Я пытаюсь реализовать функцию, которая принимает список и функцию в качестве параметров, а затем функция применяется к каждому элементу списка, а затем суммирует результат, но каждый раз, когда я запускаю программу в iex, я получаю ошибку - **(BadFunctionError) ожидал функцию, получил: 1. Не могу понять в чем проблема. Я новичок в Эликсире и функциональном программировании.
defmodule MyList do
def mapsum([], _func) do
0
end
def mapsum([head | tail], func) do
func.(head) + mapsum(tail, func.(head))
end
end
Я понял, проблема была в параметре func.(head)
внутри тела функции mapsum.
defmodule MyList do
def mapsum([], _func) do
0
end
def mapsum([head | tail], func) do
func.(head) + mapsum(tail, func)
end
end
Обратите внимание, что ответ Мохамеда, хотя и несколько правильный, не является Tail Call Оптимизированным, и, следовательно, он может взорвать стек.
Вот версия TCO.
defmodule MyListTCO do
def mapsum(list, func, acc \\ 0)
def mapsum([], _, acc), do: acc
def mapsum([head | tail], func, acc),
do: mapsum(tail, func, acc + func.(head))
end
И хотя исходная версия могла давать сбой при больших объемах ввода из-за исчерпания стека, эта версия с радостью вернулась бы.
К счастью, компилятор erlang достаточно умен, чтобы оптимизировать приведенный выше вызов для TCO, потому что он может это сделать. Но все же всегда лучше не полагаться на компилятор и помнить об этом.