Треки
/
Gleam
Gleam
/
Вправи
/
Експертні експерименти
Експертні експерименти

Експертні експерименти

Навчальна вправа

Вступ

Вирази use

У Gleam часто доводиться писати і використовувати функції вищого порядку, тобто функції, які приймають інші функції як аргументи. Іноді, коли ми використовуємо багато функцій вищого порядку одразу, код стає важко читати, бо в ньому багато рівнів відступів.

Наприклад, ось функція, яка викликає кілька функцій, що повертають Result(Int, Nil), і додає ці значення, якщо всі чотири успішні.

import gleam/result

pub fn main() -> Result(Int, Nil) {
  result.try(function1(), fn(a) {
    result.try(function2(), fn(b) {
      result.try(function3(), fn(c) {
        result.try(function4(), fn(d) {
          Ok(a + b + c + d)
        })
      })
    })
  })
}

Вирази use у Gleam дозволяють написати цей код без відступів, що часто робить його зрозумілішим.

import gleam/result

pub fn main() -> Result(Int, Nil) {
  use a <- result.try(function1())
  use b <- result.try(function2())
  use c <- result.try(function3())
  use d <- result.try(function4())
  Ok(a + b + c + d)
}

Вираз use збирає всі наступні інструкції в блоці та передає їх як функцію зворотного виклику останнім аргументом у виклику функції. Змінні між ключовим словом use і символом <- - це назви аргументів, які отримає функція зворотного виклику.

// This use expression
use a <- function(1, 2)
io.println("Hello!")
a

// Is equivalent to this normal function call
function(1, 2, fn(a) {
  io.println("Hello!")
  a
})

Функція зворотного виклику може приймати будь-яку кількість аргументів або жодного.

use a, b, c, d <- call_4_function()

use <- call_0_function()

Щоб створити функцію, яку можна викликати за допомогою виразу use, не потрібно нічого особливого, крім того, щоб вона приймала функцію зворотного виклику останнім аргументом.

pub fn call_twice(function: fn() -> t) -> #(t, t) {
  let first = function()
  let second = function()
  #(first, second)
}

Вирази use у Gleam - це дуже потужна можливість, яку можна застосувати до багатьох задач, але якщо зловживати ними, вони можуть зробити код важким для читання. Зазвичай краще використовувати звичайний синтаксис виклику функції і вдаватися до виразів use лише тоді, коли вони роблять код зрозумілішим.

Вказівки

Дафна працює над системою, яка запускає її експерименти та записує їхні результати. Частина коду стала трохи багатослівною і повторюваною, тож вона попросила нас написати кілька виразів use, які допоможуть його прибрати.

1. Визначте функцію with_retry

Іноді експеримент може не вдатися через випадкову помилку, тож якщо експеримент не вдається, Дафна хоче повторити його й подивитися, чи спрацює він із другого разу.

Визначте функцію with_retry, яка приймає як аргумент функцію, що повертає результат.

Якщо функція повертає значення Ok, то with_retry має повернути це значення.

Якщо функція повертає значення Error, то with_retry має викликати функцію ще раз і повернути результат цього виклику.

Дафна використає функцію так:

pub fn main() {
  use <- with_retry
  // Perform the experiment here
}

2. Визначте функцію record_timing

Дафна записує, скільки часу виконується кожен експеримент, викликаючи функцію запису часу до і після кожного експерименту.

Визначте функцію record_timing, яка приймає два аргументи:

  • Функція запису часу, яка не приймає аргументів і повертає Nil.
  • Функція експерименту, яка не приймає аргументів і повертає результат.

record_timing має викликати функцію запису часу, потім викликати функцію експерименту, потім знову викликати функцію запису часу й нарешті повернути результат функції експерименту.

Дафна використає функцію так:

pub fn main() {
  use <- record_timing(time_logger)
  // Perform the experiment here
}

3. Визначте функцію run_experiment

Експеримент складається з трьох фаз: підготовки, дії та запису. Усі три фази повертають результат, і кожній фазі для запуску потрібен успішний результат попередньої.

Визначте функцію run_experiment, яка приймає чотири аргументи:

  • Назва експерименту у вигляді String.
  • Функція підготовки, яка не приймає аргументів і повертає результат.
  • Функція дії, яка приймає значення Ok функції підготовки як аргумент і повертає результат.
  • Функція запису, яка приймає значення Ok функцій підготовки і дії як аргументи та повертає результат.

Якщо всі три функції завершаться успішно, то run_experiment має повернути Ok(#(experiment_name, recording_data)).

Якщо якась із функцій повертає значення Error, то run_experiment має повернути його.

Дафна використає функцію так:

pub fn main() {
  use setup_data, action_data <- run_experiment("Test 1", setup, action)
  // Record the results here
}
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Gleam Exercism

Час розпочати Експертні експерименти?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Gleam, а також 33 концепції122 вправи та справжнє наставництво від людей, і все це безкоштовно.