Naïve optimization by stepping until the error falls below a threshold As an exercise, I wanted to rewrite this toy Python code in Haskell:

def f(x):
    return abs(42-x)**2

def improve(x):
    newX = x + 0.1
    return newX, f(newX)

def optimize(f, goal):
    x = 0
    err = f(x)
    while not err &lt; goal:
        x, err = improve(x)
    return x, err

print(optimize(f, 0.5))


Ideone

My solution works but is quite ugly:

f :: (Num a) =&gt; a -&gt; a
f x = abs(42-x)^2

improve :: (Fractional a) =&gt; (a -&gt; b) -&gt; a -&gt; (a, b)
improve f x =
    let newX = x+0.1
    in (newX, f newX)

step :: (Fractional a, Ord b) =&gt; (a -&gt; b) -&gt; b -&gt; a -&gt; (a, b)
step f goal x =
    let
        newX = x+0.1
        err = f newX
    in
        if err &lt; goal then (newX, err) else step f goal newX

optimize :: (Fractional a, Ord b) =&gt; (a -&gt; b) -&gt; b -&gt; (a, b)
optimize f goal = step f goal 0

main :: IO ()
main = print $ optimize f 0.5


Ideone

I am trying to find a solution without explicit recursion using a fold or something, but did not have an idea yet on how to do it. Can anybody help me out?
The guys at #haskell pointed me to until. This makes it satisfactory to me.

f :: Num a =&gt; a -&gt; a
f x = abs(42-x)^2

improve :: Fractional b =&gt; (b -&gt; c) -&gt; (b, a) -&gt; (b, c)
improve f (x, _) = (newX, f newX) where newX = x+0.1

optimize:: (Ord a, Fractional b) =&gt; (b -&gt; a) -&gt; a -&gt; b -&gt; (b, a)
optimize f goal x = until isDone (improve f) (0, f x)
    where isDone (_, err) = err &lt; goal

main :: IO ()
main = print $ optimize f 0.5 0


http://ideone.com/ZlC7x8