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.
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.
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
}
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:
Nil.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
}
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:
String.Ok da função de preparação e devolve um resultado.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
}
Inscreve-te no Exercism para aprenderes e dominares Gleam com 33 conceitos122 exercícios, e mentoria humana real, tudo grátis.