3

有没有办法让 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。

4

1 回答 1

9

使用模板 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
于 2014-03-31T02:02:44.583 回答