J'essaie de comprendre comment appeler des fonctions correctement récursives dans des expressions de calcul et ne pas obtenir d'exception de dépassement de pile. Si je comprends bien ce problème est connu, mais ne peut toujours pas saisir le concept. Peut-être que quelqu'un a des explications ou des exemples simples pour cela.Liaison r # recursive dans les expressions de calcul et la récursivité de queue
Voici mon exemple je veux constructeur tracer ont un comportement similaire à seq
mais ne fonctionne pas avec seq monade au lieu d'une autre, par exemple option
et le retour ne dernière valeur non Aucun de la boucle récursive. C'est possible ?
Ceci est par exemple juste, le code fonctionnera à l'infini, mais il est ne devrait pas être exception stackowerflow
Si je comprends un problème de débordement de pile dans Combiner la méthode, le code juste continuer à appeler la fonction f() dans la boucle récursive, et je veux éviter ceci et rendre cette queue d'invocation récursive, ie le code devrait être compilé en boucle régulière.
type TraceBuilder() =
member __.Bind (m: int Option, f: int -> int Option) : int Option =
match m with
| Some(v) -> f v
| None -> None
member this.Yield(x) = Some x
member this.YieldFrom(x) = x
member __.Delay(f) = f
member __.Run(f) = f()
member __.Combine (a, f) =
match a with
| Some _ -> a
| None -> f()
let trace = new TraceBuilder()
let rec iterRec (xopt: int Option) =
trace {
yield! None
let! x = xopt
yield! iterRec(Some(x + 1))
}
[<EntryPoint>]
let main argv =
let x = iterRec(Some(0))
//x = startFrom(0) |> Seq.take(5000) |> Seq.toList |> ignore
printfn "%A" x
Code de réflexion dans comp. expression doit est compilé
let iterRec xopt =
combine (None, (fun() ->
bind(xopt, fun x -> iterRec(Some(x+ 1)))
Et ressemble dans ce cas d'invocation iterRec est pas récursive queue, ce qui est donc pourquoi stackoveflow, est-il possible de mettre en œuvre cette récursive de queue logique?
Lisez ces liens, ne peut toujours pas comprendre la solution:
(How) can I make this monadic bind tail-recursive?
Voici la suggestion comment résoudre le problème en utilisant FsControl lib, mais est-il possible de résoudre le problème en utilisant des expressions régulières de calcul?
Recursive functions in computation expressions
Avoiding stack overflow (with F# infinite sequences of sequences)
https://fsharpforfunandprofit.com/posts/computation-expressions-builder-part5/
L'invocation de 'f()' dans 'Combine' est déjà récursive. Ce n'est pas très clair quel est votre problème. Peut-être que cela vous aiderait si vous pouviez construire un exemple plus petit. –
J'ai mis à jour l'extrait de code le plus concis possible qui pourrait être compilé. – baio
Vous ne savez toujours pas quel problème vous rencontrez. –