Percursos
/
Gleam
Gleam
/
Exercícios
/
Experiências de Especialistas
Experiências de Especialistas

Experiências de Especialistas

Exercício de aprendizagem

Introdução

Expressões use

Em Gleam é comum escrever e usar funções de ordem superior, ou seja, funções que recebem outras funções como argumentos. Por vezes, quando se usam várias funções de ordem superior ao mesmo tempo, o código pode tornar-se difícil de ler, com muitos níveis de indentação.

Por exemplo, aqui está uma função que chama várias funções que devolvem Result(Int, Nil) e soma os valores se as quatro tiverem sucesso.

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

As expressões use de Gleam permitem-nos escrever este código sem a indentação, o que muitas vezes o torna mais fácil de ler.

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

Uma expressão use recolhe todas as instruções seguintes do bloco e passa-as, como função de callback, ao argumento final da chamada da função. As variáveis entre a palavra-chave use e o símbolo <- são os nomes dos argumentos que serão passados à função de callback.

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

A função de callback pode receber qualquer número de argumentos, ou nenhum.

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

use <- call_0_function()

Não há requisitos especiais para criar uma função que possa ser chamada com uma expressão use, a não ser receber uma função de callback como argumento final.

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

As expressões use de Gleam são uma funcionalidade muito poderosa, que pode ser aplicada a muitos problemas, mas, quando usadas em excesso, podem tornar o código difícil de ler. Em geral, prefere-se usar a sintaxe normal de chamada de funções e recorrer às expressões use apenas quando tornam o código mais fácil de ler.

Instruções

A Daphne tem andado a trabalhar num sistema para correr e registar os resultados das suas experiências. Parte do código tornou-se um pouco verboso e repetitivo, por isso pediu-te que escrevesses algumas expressões use para o ajudar a limpá-lo.

1. Define a função with_retry

Por vezes, as experiências podem falhar devido a um erro pontual, por isso, se uma experiência falhar, a Daphne quer tentá-la novamente para ver se funciona à segunda.

Define a função with_retry, que recebe como argumento uma função que devolve um resultado.

Se a função devolver um valor Ok, a função with_retry deve devolver esse valor.

Se a função devolver um valor Error, a função with_retry deve chamar a função outra vez e devolver o resultado dessa chamada.

A Daphne vai usar a função assim:

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

2. Define a função record_timing

A Daphne regista quanto tempo cada experiência demora a correr, chamando uma função de registo de tempo antes e depois de cada experiência.

Define a função record_timing, que recebe dois argumentos:

  • Uma função de registo de tempo, que não recebe argumentos e devolve Nil.
  • Uma função de experiência, que não recebe argumentos e devolve um resultado.

A função record_timing deve chamar a função de registo de tempo, depois chamar a função de experiência, depois chamar outra vez a função de registo de tempo e, por fim, devolver o resultado da função de experiência.

A Daphne vai usar a função assim:

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

3. Define a função run_experiment

As experiências são compostas por três fases. A preparação, a ação e o registo. As três fases devolvem resultados e cada fase precisa do resultado bem-sucedido da fase anterior para correr.

Define a função run_experiment, que recebe quatro argumentos:

  • O nome da experiência, como String.
  • Uma função de preparação, que não recebe argumentos e devolve um resultado.
  • Uma função de ação, que recebe como argumento o valor Ok da função de preparação e devolve um resultado.
  • Uma função de registo, que recebe como argumentos o valor Ok das funções de preparação e de ação e devolve um resultado.

Se as três funções forem bem-sucedidas, a função run_experiment deve devolver Ok(#(experiment_name, recording_data)).

Se alguma das funções devolver um valor Error, a função run_experiment deve devolver esse valor.

A Daphne vai usar a função assim:

pub fn main() {
  use setup_data, action_data <- run_experiment("Test 1", setup, action)
  // Record the results here
}
Editar via GitHub A ligação abre numa nova janela ou separador
Gleam Exercism

Estás pronto para começar Experiências de Especialistas?

Inscreve-te no Exercism para aprenderes e dominares Gleam com 33 conceitos122 exercícios, e mentoria humana real, tudo grátis.