GO!!! Alright! now we're finally anealling us picnic! here's our main "loop":
```
let anneal_tick :: MotionFunction a -> TransitionProbabilityFunction -> EnergyFunction a -> Float -> (StdGen,a) -> (StdGen,a)
anneal_tick mf tpf ef t (r,p) = let (r2,p2) = mf r p
(n ,r3) = random r2
in (r3,
if n < tpf (ef p) (ef p2) t
then p2
else p)

let anneal :: EnergyFunction a -> MotionFunction a -> TransitionProbabilityFunction -> TemperatureFunction -> Int -> StdGen -> a -> a
anneal ef mf tpf tf m r s = snd \$ foldl' (flip (anneal_tick mf tpf ef)) (r,s) (map (tf m) [0..m])

random_generator <- getStdGen

putStr "starting annealing... "
putStr "number of annealing steps: "
print annealing_time

let ideal_placement = anneal
(picnicEnergy sitting)
(picnicMotion walking)
picnicTransitionalProbability
picnicTemperature
annealing_time
random_generator
starting_placement

writeFile "tut9.svg" \$ writePolygons \$ map (similarityLine ideal_placement) sitting

putStr "Done!\nfinal energy: "
print \$ picnicEnergy sitting ideal_placement
putStr "final temperature: "
print \$ picnicTemperature 0 annealing_time
```
 Now, if we run our the completed program, we'll calculate ourselves low energy, crystallized picnic exactly as we wanted: (be patient it'll might take 5 minutes for a result...)
```> runHaskell tutorial.hs

Hello World! Let's have a picnic!
Number of people coming: 200
starting energy: 16010
starting temperature: 0.33689734
starting annealing... number of annealing steps: 500
Done!
final energy: 15010
final temperature: 0.0
```

 Now let's look at our crowning achievement, tut9.svg- Check out the bluer color, compared to the previous picture, of an annealed picnic:
before
after
 Here's what it looks like with a much longer annealing time:
 WooHoo! Now let's figure out what this final piece of code is all about... First, we have the anneal_tick function, which handles a single moment in time for our annealing... It needs to be handed three of the four annealing functions... Instead of the fourth one, TemperatureFunction, it is handed just the temperature at that moment (the Float), since at any given time the temperature is just a single number. The last thing passed into this function is the current placement of our "atoms", as well as a random number source, StdGen... In Haskell, you can't just pull random numbers out of "thin air" as you can in almost any other programming language known to mankind... Remember, doing unpredictable stuff that isn't specified explicitly in a function's type signature is a Haskell no-no... The main "loop" of our program is in the function anneal... I put "loop" in quotes because Haskellers don't use loops, they use folds... A fold is kind of like a map function: Whereas map returns a list created by thrashing through a starting list and applying a function to each member, folds return a single item, created by folding together all the items in a list into a single result value- There are two main folding functions, foldl and foldr, which fold from the left and right end of the starting list, respectively. To learn more about the different types of folds, check the HaskellWiki. Finally, we code generates the ideal_placement by glueing together all our building block functions to generate our final result- And that's the end of our tutorial program! Of course, the total number of annealing steps we're doing (500) is not enough for a very good annealing- You'd need to run a few million steps and use GHC to compile the program to machine language to get an optimal result- Here's how you'd compile it:
`ghc -O2 -fglasgow-exts -optc-march=pentium4 -optc-O2 -optc-mfpmath=sse -optc-msse2 --make picnic.hs`