Tracks
/
Gleam
Gleam
/
Übungen
/
Expertenexperimente
Expertenexperimente

Expertenexperimente

Lernübung

Einführung

use-Ausdrücke verwenden

In Gleam ist es üblich, Funktionen höherer Ordnung zu schreiben und zu verwenden, also Funktionen, die andere Funktionen als Argumente nehmen. Wenn man viele Funktionen höherer Ordnung gleichzeitig verwendet, kann der Code manchmal schwer lesbar werden, weil viele Einrückungsebenen entstehen.

Zum Beispiel: Hier ist eine Funktion, die mehrere Funktionen aufruft, die Result(Int, Nil) zurückgeben, und die Werte summiert, wenn alle vier erfolgreich sind.

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

Gleams use-Ausdrücke ermöglichen es uns, diesen Code ohne die Einrückung zu schreiben, was ihn oft leichter lesbar macht.

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

Ein use-Ausdruck sammelt alle folgenden Anweisungen im Block und übergibt sie als Callback-Funktion als letztes Argument an den Funktionsaufruf. Die Variablen zwischen dem use-Schlüsselwort und dem <--Symbol sind die Namen der Argumente, die an die Callback-Funktion übergeben werden.

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

Die Callback-Funktion kann eine beliebige Anzahl von Argumenten annehmen, oder gar keine.

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

use <- call_0_function()

Es gibt keine besonderen Voraussetzungen, um eine Funktion zu erstellen, die mit einem use-Ausdruck aufgerufen werden kann, außer dass sie eine Callback-Funktion als letztes Argument annimmt.

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

Gleams use-Ausdrücke sind ein sehr mächtiges Sprachfeature, das auf viele Probleme angewendet werden kann, aber bei übermäßigem Gebrauch machen sie den Code schwer lesbar. Im Allgemeinen ist es besser, die normale Funktionsaufruf-Syntax zu verwenden und nur dann zu use-Ausdrücken zu greifen, wenn sie den Code leichter lesbar machen.

Anleitung

Daphne hat an einem System gearbeitet, mit dem sie ihre Experimente ausführen und die Ergebnisse aufzeichnen kann. Ein Teil des Codes ist etwas umständlich und repetitiv geworden, deshalb hat sie dich gebeten, ein paar use-Ausdrücke zu schreiben, die beim Aufräumen helfen.

1. Definiere die with_retry-Funktion

Manchmal können Experimente wegen eines einmaligen Fehlers fehlschlagen. Wenn ein Experiment fehlschlägt, möchte Daphne es noch einmal versuchen, um zu sehen, ob es beim zweiten Mal klappt.

Definiere die with_retry-Funktion, die eine Funktion, die ein Ergebnis zurückgibt, als Argument entgegennimmt.

Wenn die Funktion einen Ok-Wert zurückgibt, soll with_retry diesen Wert zurückgeben.

Wenn die Funktion einen Error-Wert zurückgibt, soll with_retry die Funktion erneut aufrufen und das Ergebnis dieses Aufrufs zurückgeben.

So wird Daphne die Funktion verwenden:

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

2. Definiere die record_timing-Funktion

Um festzuhalten, wie lange jedes Experiment läuft, ruft Daphne vor und nach jedem Experiment eine Zeitprotokollierungsfunktion auf.

Definiere die record_timing-Funktion, die zwei Argumente entgegennimmt:

  • Eine Zeitprotokollierungsfunktion, die keine Argumente entgegennimmt und Nil zurückgibt.
  • Eine Experimentfunktion, die keine Argumente entgegennimmt und ein Ergebnis zurückgibt.

record_timing soll die Zeitprotokollierungsfunktion aufrufen, dann die Experimentfunktion aufrufen, dann erneut die Zeitprotokollierungsfunktion aufrufen und schließlich das Ergebnis der Experimentfunktion zurückgeben.

So wird Daphne die Funktion verwenden:

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

3. Definiere die run_experiment-Funktion

Experimente bestehen aus drei Phasen: dem Aufbau, der Aktion und der Aufzeichnung. Alle drei Phasen geben Ergebnisse zurück, und jede Phase braucht das erfolgreiche Ergebnis der vorherigen Phase, um zu laufen.

Definiere die run_experiment-Funktion, die vier Argumente entgegennimmt:

  • Den Namen des Experiments als String.
  • Eine Funktion für den Aufbau, die keine Argumente entgegennimmt und ein Ergebnis zurückgibt.
  • Eine Funktion für die Aktion, die den Ok-Wert der Funktion für den Aufbau als Argument entgegennimmt und ein Ergebnis zurückgibt.
  • Eine Funktion für die Aufzeichnung, die die Ok-Werte der Funktionen für den Aufbau und die Aktion als Argumente entgegennimmt und ein Ergebnis zurückgibt.

Wenn alle drei Funktionen erfolgreich sind, soll run_experiment Ok(#(experiment_name, recording_data)) zurückgeben.

Wenn eine der Funktionen einen Error-Wert zurückgibt, soll run_experiment diesen Wert zurückgeben.

So wird Daphne die Funktion verwenden:

pub fn main() {
  use setup_data, action_data <- run_experiment("Test 1", setup, action)
  // Record the results here
}
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Gleam Exercism

Bereit, mit Expertenexperimente zu starten?

Melde dich bei Exercism an, um Gleam mit 33 Konzepte122 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.