I have some code that approximates a solution recusively, what it actually does is not important, but it works towards r’ == rt by varying mg (m guess, starting with 4.0 because I “know” that ought to be in the ballpark).
solve_m f ar st qt = solve_m' f ar st qt 4.0
where
solve_m' f ar st qt mg
| rd > precis = f' (mg - sf)
| rd < (-precis) = f' (mg + sf)
| otherwise = mg
where
f' = solve_m' f ar st qt
rt = st + qt
r' = f st ar mg
rd = rt - r'
sf = abs(rd)
What I would like to be able to do is count the number of cycles, I know the right way to do this is with the State monad, but what is the most elegant way to fit the put/get into a function like this? Make f’ a do block? Or is it simply to add a counter solve_m’ and return (counter, mg)?
Thanks!
Edit: This seems to be basically what I want, and no Monads necessary:
solve_m f ar st qt = (last (series), length(series))
where
series = takeWhile termPred (iterate solve_m' 4.0)
termPred m' = (abs (rt - (f st ar m'))) > precis
rt = st + qt
solve_m' mg
| rt > r' = (mg - sf)
| rt < r' = (mg + sf)
where
r' = f st ar mg
rd = rt - r'
sf = abs(rd)
Still looks a little messy (repeated code) but I’ll tidy it up… This is getting me acceptable results in 1/10000th of the iterations of the code it will replace!
Without looking at your algorithm, the generic way to do this is divide up your termination criteria from the iterative algorithm:
then use either iterate and takeWhile:
or unfold:
EDIT: also notice these two intermediates are slightly different in that the first maintains the base case (the input
a, hence the- 1) while the second does not and thus would have a minor difference in the complementaryresultAndRecursions.