Ho una funzione in cui la linea a stella è una congiunzione che implica una chiamata ricorsiva. Poiché le congiunzioni funzionano, se h1 <> h2
la chiamata ricorsiva non verrà eseguita. Ma se la chiamata è fatta, allora il compilatore farà ancora marcia indietro ed eseguirà una serie di congiunzioni oltre i valori true
? O eliminerà questo passaggio inutile?La seguente funzione è ricorsiva in coda?
In altre parole, la seguente funzione è efficacemente ricorsiva?
let isExtensionOf<'A when 'A : equality> (lst1 : list<'A>) (lst2 : list<'A>) : bool =
let rec helper (currLst1 : list<'A>) (currLst2 : list<'A>) : bool =
match currLst1, currLst2 with
| h1 :: _, [] -> false
| [], _ -> true
| h1 :: t1, h2 :: t2 -> (h1 = h2) && (helper t1 t2) // *
helper lst1 lst2
sì, lo so che la linea recitato dovrebbe essere scritto if h1 = h2 then helper t1 t2 else false
. Ma sono solo curioso
Grazie in anticipo.
modo più semplice per rispondere a questo genere di domande: mangime in un elenco gigantesca, che si ritiene possano attivare il comportamento patologico e vedere cosa succede. –
Vorrei piuttosto compilarlo e quindi guardare il codice risultante con ILSpy. Più affidabile. Si noti inoltre che il risultato potrebbe differire a seconda che le ottimizzazioni siano abilitate. –
Beh, ha gestito liste di cardinalità '1.00.000.000' (cento milioni) senza battere ciglio, quindi supporrò che la mia domanda possa essere risolta in senso affermativo. – Shredderroy