有没有办法让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。
答案 0 :(得分: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