Menu
Coddy logo textTech

Возврат функций

Часть раздела Логика и потоки выполнения путешествия по R на Coddy. Урок 29 из 64.

Функция также может возвращать функцию. make_multiplier(3) возвращает новую функцию, которая умножает свой аргумент на 3:

make_multiplier <- function(n) {
  function(x) x * n
}
triple <- make_multiplier(3)
print(triple(5))
print(make_multiplier(10)(5))

Вывод:

[1] 15
[1] 50

Возвращаемая функция запоминает значения, с которыми она была создана. Это сочетание функции и окружающих её переменных называется замыканием. Каждый вызов функции-фабрики создаёт отдельное замыкание:

make_greeter <- function(greeting) {
  function(name) paste0(greeting, ", ", name, "!")
}
hello <- make_greeter("Hello")
hola <- make_greeter("Hola")
print(hello("Ada"))
print(hola("Ada"))

Вывод:

[1] "Hello, Ada!"
[1] "Hola, Ada!"

Функция-создатель превращает несколько настроек в готовый инструмент, например конвертер между единицами измерения:

make_converter <- function(factor, offset = 0) {
  function(x) x * factor + offset
}
c_to_f <- make_converter(1.8, 32)
km_to_miles <- make_converter(0.621)
print(c_to_f(100))
print(km_to_miles(10))

Результат:

[1] 212
[1] 6.21

Функции можно объединять в новые функции. compose(f, g) возвращает функцию, которая сначала выполняет f, а затем g:

compose <- function(f, g) function(x) g(f(x))
clean <- compose(trimws, toupper)
print(clean("  hi there "))

Результат:

[1] "HI THERE"
challenge icon

Задание

Легко

Реализуйте make_formatter(prefix, digits). Она возвращает функцию, которая принимает число и возвращает prefix, за которым следует число с digits знаками после запятой: make_formatter("$", 2)(3.5) возвращает $3.50.

sprintf("%.*f", digits, x) форматирует x, используя digits знаков после запятой.

Предоставленный код считывает префикс, количество знаков после запятой и список чисел, разделённых запятыми. Он создаёт один форматировщик и выводит его результат для каждого числа.

Попробуйте сами

make_formatter <- function(prefix, digits) {
  # Напишите свой код здесь
  function(x) ""
}

# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
fmt <- make_formatter(input[1], as.integer(input[2]))
for (x in as.numeric(strsplit(input[3], ",")[[1]])) cat(fmt(x), "\n", sep = "")
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и потоки выполнения

Потренируйтесь самостоятельно: Онлайн-компилятор R