gpt4 book ai didi

haskell - 如何强制 where 子句中的绑定(bind)成为 CAF?

转载 作者:行者123 更新时间:2023-12-02 02:42:45 25 4
gpt4 key购买 nike

我有一些绑定(bind),我想对函数保持私有(private)(因此,未在顶级模块命名空间中声明),但是计算起来很昂贵,所以我希望它们是 CAF。我可以使用编译指示或其他技巧来强制 GHC 为这些绑定(bind)分配 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)

如果这是不可能的,我会看到一些选项,但每个选项都有其自身的缺点:
  • 将每个函数移动到它自己的模块中,这样我就可以将昂贵的绑定(bind)移动到顶级模块命名空间,而不必担心其他函数访问它们。由于我预计会有很多这样的功能,模块的数量会爆炸式增长(一个大型项目中有数百个)。而且我不喜欢在 node.js 社区中宣传的每个模块宗教唯一的单一功能。
  • 将绑定(bind)移动到顶级模块 namespace ,并为每个模块指定一个足够唯一的名称以避免冲突,并清楚地表明它们是私有(private)的(例如 headerStyle -> header__headerStyle )。
  • 使用TemplateHaskell将昂贵的计算卸载到编译时。
  • 最佳答案

    如果我理解你的意图是正确的,这实际上很简单:只需将任何函数参数移动到 lambda 中,因此整个函数(包括 where block )是一个 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

    关于haskell - 如何强制 where 子句中的绑定(bind)成为 CAF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41401528/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com