트랙
/
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)
        })
      })
    })
  })
}

Gleam의 use 표현식을 사용하면 들여쓰기 없이 이 코드를 작성할 수 있어서, 대개 읽기가 더 쉬워져요.

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)
}

Gleam의 use 표현식은 많은 문제에 적용할 수 있는 아주 강력한 기능이지만, 지나치게 사용하면 코드를 읽기 어렵게 만들 수 있어요. 보통은 일반적인 함수 호출 문법을 사용하고, 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개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.