Find two numbers in a sorted array whose sum is closest to a given number
The "intermediate array" takes no extra space due to lazy evaluation. minimumBy . comparing is minimumOn. Yes, swapping the parameters makes sense. Inline then and else once more. I wouldn't worry so much about constant factors - have you compiled it with -O2 and tested (eg with criterion)?

import Data.List (minimumOn)

closestPairSum :: (Num a, Ord a) =&gt; a -&gt; [a] -&gt; (a, a)
closestPairSum n xs = minimumOn (abs . (n-) . uncurry (+)) pairs where
  pairs = sums xs (reverse xs)
  sums xxs@(x:xs) yys@(y:ys) = (x, y) : if n &lt; x + y
    then sums xxs ys
    else sums xs yys
  sums _ _ = []