use
In Gleam è comune scrivere e usare funzioni di ordine superiore, cioè funzioni che accettano altre funzioni come argomenti. A volte, quando si usano molte funzioni di ordine superiore insieme, il codice può diventare difficile da leggere, con molti livelli di indentazione.
Per esempio, ecco una funzione che chiama diverse funzioni che restituiscono Result(Int, Nil) e somma i valori se tutte e quattro hanno successo.
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)
})
})
})
})
}
Le espressioni use di Gleam ci permettono di scrivere questo codice senza l'indentazione, rendendolo spesso più facile da leggere.
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)
}
Un'espressione use raccoglie tutte le istruzioni che seguono nel blocco e le passa come funzione di callback, come argomento finale, alla chiamata di funzione. Le variabili tra la parola chiave use e il simbolo <- sono i nomi degli argomenti che verranno passati alla funzione di 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 funzione di callback può accettare un numero qualsiasi di argomenti, o anche nessuno.
use a, b, c, d <- call_4_function()
use <- call_0_function()
Non ci sono requisiti speciali per creare una funzione che possa essere chiamata con un'espressione use, se non quello di accettare una funzione di callback come argomento finale.
pub fn call_twice(function: fn() -> t) -> #(t, t) {
let first = function()
let second = function()
#(first, second)
}
Le espressioni use di Gleam sono una funzionalità molto potente, che si può applicare a molti problemi, ma se usate troppo possono rendere il codice difficile da leggere. In genere è preferibile usare la normale sintassi di chiamata di funzione e ricorrere alle espressioni use solo quando rendono il codice più facile da leggere.
Daphne sta lavorando a un sistema per eseguire e registrare i risultati dei suoi esperimenti. Parte del codice è diventato un po' verboso e ripetitivo, così ti ha chiesto di scrivere alcune espressioni use per aiutarla a ripulirlo.
with_retry
A volte gli esperimenti possono fallire a causa di un errore isolato, quindi se un esperimento fallisce Daphne vuole riprovare per vedere se funziona la seconda volta.
Definisci la funzione with_retry che prende come argomento una funzione che restituisce un risultato.
Se la funzione restituisce un valore Ok, allora with_retry deve restituire quel valore.
Se la funzione restituisce un valore Error, allora with_retry deve chiamare di nuovo la funzione e restituire il risultato di quella chiamata.
Daphne userà la funzione in questo modo:
pub fn main() {
use <- with_retry
// Perform the experiment here
}
record_timing
Daphne registra quanto tempo impiega ogni esperimento chiamando una funzione di registrazione del tempo prima e dopo ogni esperimento.
Definisci la funzione record_timing che prende due argomenti:
Nil.record_timing deve chiamare la funzione di registrazione del tempo, poi la funzione di esperimento, poi di nuovo la funzione di registrazione del tempo, e infine restituire il risultato della funzione di esperimento.
Daphne userà la funzione in questo modo:
pub fn main() {
use <- record_timing(time_logger)
// Perform the experiment here
}
run_experiment
Gli esperimenti sono composti da tre fasi. La preparazione, l'azione e la registrazione. Tutte e tre le fasi restituiscono risultati, e ogni fase ha bisogno del risultato riuscito della fase precedente per essere eseguita.
Definisci la funzione run_experiment che prende quattro argomenti:
String.Ok della funzione di preparazione e restituisce un risultato.Ok delle funzioni di preparazione e azione e restituisce un risultato.Se tutte e tre le funzioni hanno successo, allora run_experiment deve restituire Ok(#(experiment_name, recording_data)).
Se una qualsiasi delle funzioni restituisce un valore Error, allora run_experiment deve restituire quel valore.
Daphne userà la funzione in questo modo:
pub fn main() {
use setup_data, action_data <- run_experiment("Test 1", setup, action)
// Record the results here
}
Iscriviti a Exercism per imparare e padroneggiare Gleam con 33 concetti122 esercizi e il mentoring di persone reali, tutto gratis.