# 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 < goal:
x, err = improve(x)
return x, err

print(optimize(f, 0.5))


Ideone

My solution works but is quite ugly:

f :: (Num a) => a -> a
f x = abs(42-x)^2

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

step :: (Fractional a, Ord b) => (a -> b) -> b -> a -> (a, b)
step f goal x =
let
newX = x+0.1
err = f newX
in
if err < goal then (newX, err) else step f goal newX

optimize :: (Fractional a, Ord b) => (a -> b) -> b -> (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? ## 1 Answer The guys at #haskell pointed me to until. This makes it satisfactory to me. f :: Num a => a -> a f x = abs(42-x)^2 improve :: Fractional b => (b -> c) -> (b, a) -> (b, c) improve f (x, _) = (newX, f newX) where newX = x+0.1 optimize:: (Ord a, Fractional b) => (b -> a) -> a -> b -> (b, a) optimize f goal x = until isDone (improve f) (0, f x) where isDone (_, err) = err < goal main :: IO () main = print$ optimize f 0.5 0


http://ideone.com/ZlC7x8