# Implements the binary-searching style code in functional way

Given that I have a code snippet written in binary-searching way:

(*
pts <-- data points
p   <-- curve degree
TOL <-- the tolerance of fitting
*)
compactCurveFit[pts_, p_, TOL_] :=
Module[{m, nLow, nUpp, nNow, Unow, Pnow, fitErr, tag = False, Uprev, Pprev},
m = Length@pts - 1;

nLow = p;
nUpp = m;
nNow = Floor[(nLow + nUpp)/2];
(* special assignment *)
Uprev = Pprev = \$Failed;

(* fit the data points in binary-seraching way *)
While[True,
{Pnow, Unow, fitErr} = curveFitStep[pts, nNow, p, TOL];
tag = fitErr <= TOL;
If[tag,
(* fit sucess *)
If[nNow - nLow <= 1,
Return[{Unow, Pnow}],
(* else *)
nUpp = nNow;
nNow = Floor[(nLow + nUpp)/2];
(* save the data of the previous step *)
Uprev = Unow;
Pprev = Pnow
],
(* else fit failed *)
If[nUpp - nNow <= 1,
Return[{Uprev, Pprev}],
(* else *)
nLow = nNow;
nNow = Floor[(nLow + nUpp)/2]
]
]
]
]


The above implementation compactCurveFit[] is straightforward in procedural language like C or Java. However, it is not elegant in Mathematica, such as the usage of Return[], While[], which is not recommended in a functional and rule-based language.

So I would like to know if it could be refactored to functional way.