/ / Memoizing funções recursivas otimizadas de chamada de cauda em F # [duplicado] - f #, memorização

Memoizing cauda funções otimizadas recursivas em F # [duplicado] - f #, memoization

Duplicar Possível:
Combinar memoização e recursão da cauda

Então, o seguinte é o código que escrevi, chamada final otimizada usando uma variável de acumulação

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

Como memorizo ​​isso? o problema que encontrei quando tentei memorizar é que a chamada recursiva tem que ir para o objeto memorizar, então você precisa ter um ... objeto recursivo?

Ou é muito mais simples e sou apenas inexperiente?

Respostas:

3 para resposta № 1

F # permite definir um valor recursivo (como objeto recursivo que você mencionou), se você tiver memoize2 para executar a memorização (assumindo uma função de dois argumentos - para torná-la compatível com o seu counter), então você pode escrever:

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)) )

Referências recursivas como essa podem ser perigosas; portanto, o F # insere algumas verificações em tempo de execução. Também dá um aviso FS0040 para notificá-lo sobre isso, mas, neste caso, orecursão está correta (um problema pode ocorrer se a referência recursiva for acessada durante a inicialização - aqui a usamos apenas mais tarde, quando a função já está declarada, para que tudo esteja bem). Você pode desativar o aviso adicionando #nowarn "40".