Tracks
/
Gleam
Gleam
/
Ejercicios
/
Experimentos de expertos
Experimentos de expertos

Experimentos de expertos

Ejercicio de aprendizaje

Introducción

Uso de expresiones

En Gleam es común escribir y usar funciones de orden superior, es decir, funciones que reciben otras funciones como argumentos. A veces, al usar muchas funciones de orden superior a la vez, el código puede volverse difícil de leer, con muchos niveles de indentación.

Por ejemplo, aquí hay una función que llama a varias funciones que devuelven Result(Int, Nil) y 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 suele hacerlo 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 sentencias siguientes en el bloque y las pasa como una función de callback como argumento final a la llamada de la función. Las variables 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 cantidad de argumentos, o ninguno.

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

use <- call_0_function()

No hay requisitos especiales para crear una función que se pueda llamar con una expresión use, aparte de recibir una función de callback como argumento final.

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 poderosa que se puede aplicar a muchos problemas, pero cuando 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 función y recurrir a las expresiones use solo cuando hacen 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 reintentarlo para ver si funciona la segunda vez.

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 cada experimento en ejecutarse 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 se componen de tres fases. La configuració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 configuració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 configuración y devuelve un resultado.
  • Una función de registro que recibe como argumentos el valor Ok de las funciones de configuración y de 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 una pestaña nuevas
Gleam Exercism

¿Todo listo para empezar Experimentos de expertos?

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