Функции в качестве аргументов - что здесь происходит? - PullRequest
0 голосов
/ 06 апреля 2019

Я прохожу некоторые коаны Эликсира и немного озадачен тем, что происходит в этих строках кода.

  def times_five_and_then(number, fun), do: fun.(number * 5)
  def square(number), do: number * number

  koan "You can pass functions around as arguments. Place an '&' before the name and state the arity" do
    assert times_five_and_then(2, &square/1) == ___
  end

Для ___ правильный ответ - 100. Но яне знаете, как и почему, кто-нибудь может сформулировать, что происходит?

1 Ответ

2 голосов
/ 06 апреля 2019

& - оператор захвата функции .&square/1 означает «захват функции с именем square, имеющей арность 1 (арность 1 на простом английском языке: принимает один аргумент)».

times_five_and_then(2, &square/1)

Это означает «вызов функции times_five_and_then счисло 2 и захват функции square (которая имеет арность 1) ".

Функция, хранящаяся в переменной, называется анонимной функцией (потому что у нее нет имени, в отличие от функцийопределяется с помощью ключевого слова def).Именованная функция может быть захвачена как анонимная функция с помощью оператора захвата &, что и происходит в вашем примере.

times_five_and_then/2 вызывает ее параметры number и fun.Параметр fun - это переменная, которая содержит анонимную функцию.Эта функция может быть любой, но в вашем примере это захват функции square/1.Синтаксис для вызова анонимной функции: variable_name.(args).Вот что в данном случае происходит с fun.(number * 5).Функция, хранящаяся в fun, вызывается с аргументом number * 5.

. Давайте рассмотрим реализацию times_five_and_then/2:

def times_five_and_then(number, fun), do: fun.(number * 5)

. Это принимает аргумент fun,и вызывает содержащуюся в нем функцию с аргументом number, умноженным на 5.Подробное описание того, что происходит:

  1. Определена функция с именем square/1, которая возводит в квадрат ее аргумент.
  2. Функция square захватывается как анонимная функция и передается в times_five_and_then/2 функция в качестве второго параметра.
  3. Функция times_five_and_then/2 связывает захваченную функцию с переменной fun.
  4. Функция times_five_and_then/2 умножает свой первый аргумент, называемый number,на пять.
  5. Функция times_five_and_then/2 вызывает анонимную функцию, хранящуюся в fun (которая является захватом функции square/2), с результатом вышеупомянутого умножения.
  6. Возвращается результат выполнения функции в fun.

Или другими словами, 2 умножается на 5, а затем передается в захват функции square/2, которая возводит его в квадрат, чтобы дать 100.

...