If I understood your intention correctly, this is actually easy: just move any function arguments to lambda, so the whole function (including the where block) is CAF:
foo :: Int -> Int foo = \x -> x * nFermat where nFermat = length [() | a<-[1..m], b<-[1..m], c<-[1..m], a^3+b^3==c^3] m = 200 main = interact $ show . foos . read where foos n = foo <$> [0..n]
Thus, regardless of the arguments x to be used, the same nFermat will be reused.
sagemuej@sagemuej-X302LA :/tmp$ time runhaskell fermata.hs <<< 1 [0,0] real 0m23.199s user 0m23.177s sys 0m0.045s sagemuej@sagemuej-X302LA :/tmp$ time runhaskell fermata.hs <<< 100 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] real 0m22.629s user 0m22.601s sys 0m0.052s