我有一些绑定,我想保持一个函数的私有(所以,不在顶级模块命名空间中声明),但是计算起来很昂贵,所以我更喜欢它们是CAF。是否有一个pragma或其他技巧可以用来强制GHC为这些绑定分配CAF?
示例代码:
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)
如果那是不可能的,我会看到一些选项,但每个选项都有其自身的缺点:
headerStyle
- > header__headerStyle
)。 TemplateHaskell
将昂贵的计算卸载到编译时。答案 0 :(得分:4)
如果我理解你的意图是正确的,这实际上很简单:只需将任何函数参数移动到lambda中,所以整个函数(包括where
块)都是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]
这样,无论您使用哪个x
参数,都会重复使用相同的nFermat
。
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