Possibile duplicato:
Combina memoization e coda-ricorsione
Quindi il seguente è il codice che ho scritto, chiamata coda ottimizzata usando una variabile di accumulo
let rec counter init count =
if init = 1 then count + 1 else
match init with
| Even value -> (counter (value/2) (1 + count))
| Odd value -> (counter ((3 * value) + 1) (count+1))
let SeqBuilder (initval:int) : int =
counter initval 0
Come posso memoize questo? il problema che ho incontrato quando ho provato a memoize è che la chiamata ricorsiva deve andare all'oggetto memoize, quindi devi avere un ... oggetto ricorsivo?
O è molto più semplice e io sono solo inesperto?
risposte:
3 per risposta № 1F # ti consente di definire a valore ricorsivo (come l'oggetto ricorsivo che hai menzionato), quindi se lo hai memoize2
funzione per fare la memoizzazione (prendendo una funzione di due argomenti - per renderlo compatibile con il tuo counter
), quindi puoi scrivere:
let rec counter = memoize2 (fun init count ->
if init = 1 then count + 1 else
match init with
| Even value -> (counter (value/2) (1 + count))
| Odd value -> (counter ((3 * value) + 1) (count+1)) )
Riferimenti ricorsivi come questo possono essere pericolosi, quindi F # inserisce alcuni controlli di runtime. Dà anche un avvertimento FS0040
per informarti di questo, ma in questo caso illa ricorsione è corretta (potrebbe verificarsi un problema se durante l'inizializzazione è stato effettuato il riferimento ricorsivo - qui lo usiamo solo più tardi, quando la funzione è già stata dichiarata, quindi tutto va bene). È possibile disabilitare l'avviso aggiungendo #nowarn "40"
.