/ / Memoizing chiamata coda ottimizzata funzioni ricorsive in F # [duplicato] - f #, memoization

Memoizing tail call funzioni ricorsive ottimizzate in F # [duplicato] - f #, memoization

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 № 1

F # 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".