Instead of (map head . map orderFitness) , where orderFitness is sortBy , you can use maximumBy and one map . This will not save too much (since you are switching from O (n log n) to O (n) and you can get a different coefficient of the two from eliminating the double card), but at least it is somewhat simpler and more efficient, you will also get rid of the call to reverse.
I doubt this fixes the problem without deepseq , but it should be improved nonetheless.
Edit: if the standard library and GHC were perfect, then head . sortBy head . sortBy would generate the identical code maximumBy and map head . map sortBy map head . map sortBy identical map (head . sortBy) code map (head . sortBy) , unfortunately, none of these things is likely to be true in practice, sortBy will tend to do a bunch of additional memory allocation, because it is a partition and conquer algorithm. Card merging is an optimization that you sometimes get, but don't count.
More importantly, using maximumBy more declarative. Itβs easier to see what the code does and how long it takes. It should also be easier to take advantage of the optimization, because we know what the goal is, and not just how we get it.
Philip jf
source share