Rutas
/
Gleam
Gleam
/
Ejercicios
/
Experimentos expertos
Experimentos expertos

Experimentos expertos

Ejercicio de aprendizaje

Introducción

Expresiones 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.

Instrucciones

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.

1. Define la función 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
}

2. Define la función 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:

  • Una función de registro de tiempo que no recibe argumentos y devuelve Nil.
  • Una función de experimento que no recibe argumentos y devuelve un resultado.

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
}

3. Define la función 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:

  • El nombre del experimento como String.
  • Una función de preparación que no recibe argumentos y devuelve un resultado.
  • Una función de acción que recibe como argumento el valor Ok de la función de preparación y devuelve un resultado.
  • Una función de registro que recibe como argumentos el valor 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
}
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Gleam Exercism

¿Listo para empezar Experimentos expertos?

Regístrate en Exercism para aprender y dominar Gleam con 33 conceptos122 ejercicios y mentoría humana real, todo gratis.