【问题标题】:Have Haskell expand certain thunks at compile time? [duplicate]Haskell 是否在编译时扩展了某些 thunk? [复制]
【发布时间】:2014-03-30 22:50:02
【问题描述】:

有没有办法让 Haskell 在运行时扩展某些 thunk。例如,说我有

--Purposely inefficient code for demonstration
fib 0=0
fib 1=1
fib n=fib n=fib (n-1) + fib (n-2)
goldRatio=fib 100 / fib 101

我如何让它在编译时评估goldRatio。例如,与

{-# EVALUATE goldRatio #-}

它只需要弱头部形式,因为Control.Deepseq.force 可以处理其余的。我听说模板haskell可以做到这一点,但我不太了解。

注意:我目前正在使用 GHC。

【问题讨论】:

    标签: haskell compilation evaluation thunk


    【解决方案1】:

    使用模板 haskell 非常简单。首先,在一个模块中定义代码:

    module Test where
    --Purposely inefficient code for demonstration
    fib 0=0
    fib 1=1
    fib n=fib (n-1) + fib (n-2)
    

    然后在另一个模块中使用带有模板 haskell 的代码创建值。您必须在另一个模块中执行此操作,因为模板 haskell 定义不能调用在同一模块中定义的函数。

    {-# LANGUAGE TemplateHaskell #-}
    import Test
    import Language.Haskell.TH
    import Data.Ratio
    
    goldRatio :: Double
    goldRatio = $(litE (rationalL (toRational $ fib 21 / fib 20)))
    

    现在编译将花费更长的时间,但goldRatio 现在将是一个固定值并在运行时立即计算。它就像您在源代码中键入 goldRatio = 1.6180339985218033 一样运行。使用示例:

    > goldRatio
    1.6180339985218033
    

    【讨论】:

    • goldRatio = $(let x = fib 20 / fib 21 in [| x |]) 也有效。 let 绑定是必要的,这有点迟钝,但结果是不需要额外的导入。直到您需要编写一个 Lift 实例才能使其工作。
    猜你喜欢
    • 2023-04-02
    • 2014-01-19
    • 2020-12-22
    • 2014-11-16
    • 2010-12-14
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多