Euler #4: Refined Palindrome in Haskell This is my attempt at the Problem Euler #4 in Haskell ("Find the largest palindrome made from the product of two 3-digit numbers.")

import Data.List

isPalindrome :: Show a =&gt; a -&gt; Bool
isPalindrome n = l == reverse l
  where l = show n

maxPalindrome :: (Integral a, Show a) =&gt; a
maxPalindrome = maximum $ head . transpose $ allPalindrome &lt;$&gt; [999, 998 .. 1]
  where allPalindrome x = filter (isPalindrome) $ (x *) &lt;$&gt; [999, 998 .. x]


To my surprise I didn't see any such optimisation in the snippets I found (the head . transpose is there to only consider the highest of each pairs), which surprised me. However this is still running about 0.5 seconds which I find still slow?

Is there a way to make it run faster? I am aware of Project Euler #4 in Haskell however, my question is not about the algorithm I use but about its implementation.

Do you have any other recommendation about my code?

Thank you very much in advance
Your code is fine, but I would suggest some small changes. Instead of head . transpose, I would use concatMap (take 1). This captures your intend to take the first (and therefore largest) number from each allPalindrome.

Next, I would use Int instead of (Integral a, Show a), since 999 * 999 is smaller than maxBound :: Int. Why? Because by default, Integer will be used for Integral types, if they were note specified. Therefore, you end up with maxPalindrome handled as a Integer, which is slower than Int.

And last, but not least, I would stop at 111, since 111 * 111 is a palindrome. 

We end up with:

isPalindrome :: Show a =&gt; a -&gt; Bool
isPalindrome n = l == reverse l
  where l = show n

maxPalindrome :: Int
maxPalindrome = maximum $ concatMap (take 1) $ allPalindrome &lt;$&gt; [999, 998 .. 111]
  where allPalindrome x = filter isPalindrome $ (x *) &lt;$&gt; [999, 998 .. x]

main :: IO ()
main = print maxPalindrome


Note that you should compile your code if you want to check its performance.

Alternatively, if you want to keep maxPalindrome's type, use :: Int:

maxPalindrome :: (Integral n, Show n) =&gt; n
maxPalindrome = maximum $ concatMap (take 1) $ allPalindrome &lt;$&gt; [999, 998 .. 111]
  where allPalindrome x = filter isPalindrome $ (x *) &lt;$&gt; [999, 998 .. x]

main :: IO ()
main = print (maxPalindrome :: Int)