Ho studiato Haskell per alcune settimane e ho una domanda sull'uso del trattino basso (_
) come parametro di funzione. Penso che la mia domanda sarà meglio chiesta con un esempio specifico. Diciamo che voglio definire una funzione che estrae l'elemento di una lista in base all'indice fornito-sì, mi rendo conto che (!!)
è già predefinito. I due modi che posso definire la funzione (sono sicuro che ci sono più) sono i seguenti:Haskell underscore vs. variabile esplicita
Versione 1
indexedElement :: [a] -> Int -> a
indexedElement xs n | n < 0 = error "Index can not be negative."
indexedElement [] n = error "Index must be smaller than the length of the list."
indexedElement (x:xs) 0 = x
indexedElement (x:xs) n = indexedElement xs (n - 1)
Versione 2
indexedElement :: [a] -> Int -> a
indexedElement _ n | n < 0 = error "Index can not be negative."
indexedElement [] _ = error "Index must be smaller than the length of the list."
indexedElement (x:_) 0 = x
indexedElement (_:xs) n = indexedElement xs (n - 1)
I due le versioni sono ovviamente molto simili. L'unica differenza tra i due è l'uso di una variabile esplicita o di un carattere di sottolineatura. Per me _
significa che letteralmente tutto può essere scritto lì mentre una variabile esplicita come n
rende più ovvio che l'argomento deve essere un numero intero. Per questo motivo, preferisco la versione 1; ma il codice sorgente GHC per (!!)
è scritto come la Versione 2. Esiste un vantaggio funzionale della seconda versione? In caso contrario, i programmatori "hardcore" di Haskell hanno problemi con la versione 1? Capisco l'importanza di avere un modo coerente di scrivere il codice, quindi cerco di seguire le "regole non scritte" per la programmazione in una determinata lingua. Questo è un esempio in cui preferisco di gran lunga la prima versione, e non credo che renda il codice più difficile da leggere. Non so se è dovuto al mio passato in matematica o cosa, ma mi piacerebbe sapere cosa ne pensano i veterinari di Haskell.
io non sono sicuro di differenze di prestazioni (si potrebbe provare emettendo il nucleo di entrambe le versioni per vedere se ci sono differenze), ma la maggior parte degli haskeller preferirebbe la seconda versione poiché riduce il numero di nomi che devono essere associati. Il '_' significa che qualsiasi valore può andare lì (purché sia il tipo giusto, che è dato dalla firma del tipo.) Anche se può sembrare più naturale usare' n' per indicare un numero intero anche quando non è in uso, tenere presente che non tutti avranno questo pregiudizio – bheklilr
È possibile scendere a compromessi nominando la variabile '_n', che disattiva gli avvertimenti quando si utilizza' -Wall', indica che la variabile non viene utilizzata e la nomina nello stesso momento. – luqui
@bheklilr Ok, apprezzo il tuo contributo, mi allenerò per ottenere più a mio agio con '_'. Grazie – basketballfan22