I have some bindings which I want to keep private to a function (so, not declared in the top-level module namespace), but which are expensive to compute so I'd prefer them to be CAFs. Is there a pragma or some other trick I could use to force GHC to allocate a CAF for those bindings?
example code:
header :: HeaderProps -> Element
header = div_ [style_ headerStyle] [str_ "Here be headerz"]
where
-- Creating the 'headerStyle' is expensive! Do it only once
-- regardless of how many times the 'header' function is used.
headerStyle = mkStyle $ do
display flex
flexDirection column
padding (px 20) (px 40)
If that is not possible, I see a few options, but each has its own drawbacks:
headerStyle
-> header__headerStyle
).TemplateHaskell
to offload the expensive computations to compile-time.If I've understood your intent correct, this is actually easy: just move any function arguments into a lambda, so the entire function (including the where
block) is a 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]
This way, whatever x
arguments you use, 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With