Parcours
/
Gleam
Gleam
/
Exercices
/
Expériences d'expert
Expériences d'expert

Expériences d'expert

Exercice d'apprentissage

Introduction

Utilise les expressions

En Gleam, il est courant d'écrire et d'utiliser des fonctions d'ordre supérieur, c'est-à-dire des fonctions qui prennent d'autres fonctions en arguments. Parfois, lorsqu'on utilise de nombreuses fonctions d'ordre supérieur en même temps, le code peut devenir difficile à lire, avec de nombreuses couches d'indentation.

Par exemple, voici une fonction qui appelle plusieurs fonctions qui renvoient Result(Int, Nil), et additionne les valeurs si les quatre réussissent.

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

Les expressions use de Gleam permettent d'écrire ce code sans l'indentation, ce qui le rend souvent plus facile à lire.

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

Une expression use rassemble toutes les instructions suivantes du bloc et les passe sous forme de fonction de rappel comme dernier argument de l'appel de fonction. Les variables entre le mot-clé use et le symbole <- sont les noms des arguments qui seront passés à la fonction de rappel.

// 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 fonction de rappel peut prendre n'importe quel nombre d'arguments, ou aucun.

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

use <- call_0_function()

Il n'y a pas d'exigences particulières pour créer une fonction qui peut être appelée avec une expression use, si ce n'est qu'elle prend une fonction de rappel comme dernier argument.

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

Les expressions use de Gleam sont une fonctionnalité très puissante qui peut s'appliquer à beaucoup de problèmes, mais lorsqu'on en abuse, elles peuvent rendre le code difficile à lire. Il est généralement préférable d'utiliser la syntaxe d'appel de fonction normale et de ne recourir aux expressions use que lorsqu'elles rendent le code plus facile à lire.

Instructions

Daphne travaille sur un système qui exécute et enregistre les résultats de ses expériences. Une partie du code est devenue un peu verbeuse et répétitive, alors elle t'a demandé d'écrire quelques expressions use pour l'aider à le nettoyer.

1. Définis la fonction with_retry

Il arrive qu'une expérience échoue à cause d'une erreur ponctuelle ; dans ce cas, Daphne veut la relancer pour voir si elle fonctionne du deuxième coup.

Définis la fonction with_retry, qui prend en argument une fonction qui renvoie un résultat.

Si la fonction renvoie une valeur Ok, alors with_retry doit renvoyer cette valeur.

Si la fonction renvoie une valeur Error, alors with_retry doit rappeler la fonction et renvoyer le résultat de cet appel.

Daphne utilisera la fonction comme ceci :

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

2. Définis la fonction record_timing

Daphne enregistre la durée d'exécution de chaque expérience en appelant une fonction de journalisation du temps avant et après chaque expérience.

Définis la fonction record_timing, qui prend deux arguments :

  • Une fonction de journalisation du temps qui ne prend aucun argument et renvoie Nil.
  • Une fonction d'expérience qui ne prend aucun argument et renvoie un résultat.

record_timing doit appeler la fonction de journalisation du temps, puis appeler la fonction d'expérience, puis appeler à nouveau la fonction de journalisation du temps, et enfin renvoyer le résultat de la fonction d'expérience.

Daphne utilisera la fonction comme ceci :

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

3. Définis la fonction run_experiment

Une expérience se déroule en trois phases. La préparation, l'action et l'enregistrement. Les trois phases renvoient un résultat, et pour s'exécuter, chacune a besoin que la phase précédente ait renvoyé un résultat positif.

Définis la fonction run_experiment, qui prend quatre arguments :

  • Le nom de l'expérience, sous forme de String.
  • Une fonction de préparation qui ne prend aucun argument et renvoie un résultat.
  • Une fonction d'action qui prend en argument la valeur Ok de la fonction de préparation et renvoie un résultat.
  • Une fonction d'enregistrement qui prend en argument les valeurs Ok des fonctions de préparation et d'action et renvoie un résultat.

Si les trois fonctions réussissent, alors run_experiment doit renvoyer Ok(#(experiment_name, recording_data)).

Si l'une des fonctions renvoie une valeur Error, alors run_experiment doit renvoyer cette valeur.

Daphne utilisera la fonction comme ceci :

pub fn main() {
  use setup_data, action_data <- run_experiment("Test 1", setup, action)
  // Record the results here
}
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Gleam Exercism

Prêt à commencer Expériences d'expert ?

Inscris-toi sur Exercism pour apprendre et maîtriser Gleam avec 33 concepts122 exercices, et un vrai mentorat humain, le tout gratuitement.