use
En Gleam es habitual escribir y usar funciones de orden superior, es decir, funciones que reciben otras funciones como argumentos. A veces, cuando se usan muchas funciones de orden superior a la vez, el código puede volverse difícil de leer, con muchas capas de indentación.
Por ejemplo, aquí tienes una función que llama a varias funciones que devuelven Result(Int, Nil) y que suma los valores si las cuatro tienen éxito.
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)
})
})
})
})
}
Las expresiones use de Gleam nos permiten escribir este código sin la indentación, lo que a menudo lo hace más fácil de leer.
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)
}
Una expresión use recoge todas las instrucciones que vienen a continuación en el bloque y las pasa, en forma de función de callback, como último argumento de la llamada a la función. Las variables que hay entre la palabra clave use y el símbolo <- son los nombres de los argumentos que se pasarán a la función 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
})
La función de callback puede recibir cualquier número de argumentos, o ninguno.
use a, b, c, d <- call_4_function()
use <- call_0_function()
No hay ningún requisito especial para crear una función que se pueda llamar con una expresión use, aparte de que reciba una función de callback como último argumento.
pub fn call_twice(function: fn() -> t) -> #(t, t) {
let first = function()
let second = function()
#(first, second)
}
Las expresiones use de Gleam son una funcionalidad muy potente que se puede aplicar a multitud de problemas, pero, si se abusa de ellas, pueden hacer que el código sea difícil de leer. Por lo general, se prefiere usar la sintaxis normal de llamada a funciones y recurrir a las expresiones use solo cuando hagan que el código sea más fácil de leer.
Daphne ha estado trabajando en un sistema para ejecutar y registrar los resultados de sus experimentos. Parte del código se ha vuelto un poco verboso y repetitivo, así que te ha pedido que escribas algunas expresiones use para ayudarla a limpiarlo.
with_retry
A veces los experimentos pueden fallar por un error puntual, así que, si un experimento falla, Daphne quiere volver a intentarlo para ver si funciona a la segunda.
Define la función with_retry, que recibe como argumento una función que devuelve un resultado.
Si la función devuelve un valor Ok, with_retry debe devolver ese valor.
Si la función devuelve un valor Error, with_retry debe llamar a la función de nuevo y devolver el resultado de esa llamada.
Daphne usará la función así:
pub fn main() {
use <- with_retry
// Perform the experiment here
}
record_timing
Daphne registra cuánto tarda en ejecutarse cada experimento llamando a una función de registro de tiempo antes y después de cada experimento.
Define la función record_timing, que recibe dos argumentos:
Nil.record_timing debe llamar a la función de registro de tiempo, luego llamar a la función de experimento, después llamar de nuevo a la función de registro de tiempo y, por último, devolver el resultado de la función de experimento.
Daphne usará la función así:
pub fn main() {
use <- record_timing(time_logger)
// Perform the experiment here
}
run_experiment
Los experimentos constan de tres fases: la preparación, la acción y el registro. Las tres fases devuelven resultados, y cada fase necesita el resultado exitoso de la fase anterior para ejecutarse.
Define la función run_experiment, que recibe cuatro argumentos:
String.Ok de la función de preparación y devuelve un resultado.Ok de las funciones de preparación y acción y devuelve un resultado.Si las tres funciones tienen éxito, run_experiment debe devolver Ok(#(experiment_name, recording_data)).
Si alguna de las funciones devuelve un valor Error, run_experiment debe devolver ese valor.
Daphne usará la función así:
pub fn main() {
use setup_data, action_data <- run_experiment("Test 1", setup, action)
// Record the results here
}
Regístrate en Exercism para aprender y dominar Gleam con 33 conceptos122 ejercicios y mentoría humana real, todo gratis.