Find biggest palindrome which is the product of two 3-digit numbers
isPalindrome is ok here, no need to make it faster.
In functional programming functions are everywhere, even inside other functions and this is ok. Using ViewPatterns extension it is possible to rewrite is3x3 as:

is3x3 n = any cond [101..999]
    where
        cond (divMod n -&gt; (d, 0)) = 99 &lt; d &amp;&amp; d &lt;= 999
        cond _ = False

I don't know any readable way to rewrite cond2 without parenthesis.
Haskell is smart enough to calculate 999^2 and 999^2-1 at compile time. In terms of performance, if you don't specify end of the list there will be no checks for the end of the list at runtime (which is good in this case).




Using Integer is justified only for big numbers, in your case using Int is enough and could be a bit faster.

Here is another solution:

main = print $ maximum
  [ x * y :: Int
  | x &lt;- [999, 998 .. 100]
  , y &lt;- [x, x-1 .. 100]
  , (==) &lt;*&gt; reverse $ show $ x * y
  ]