让Haskell在编译时扩展某些thunk?

PyR*_*lez 3 evaluation haskell compilation thunk

有没有办法让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
Run Code Online (Sandbox Code Playgroud)

我怎么能goldRatio在编译时评估它.例如,与

{-# EVALUATE goldRatio #-}
Run Code Online (Sandbox Code Playgroud)

它只需要弱头形状,因为Control.Deepseq.force可以处理其余部分.我听说模板haskell可以做到这一点,但我不太清楚.

注意:我现在正在使用GHC.

Dav*_*ani 9

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

module Test where
--Purposely inefficient code for demonstration
fib 0=0
fib 1=1
fib n=fib (n-1) + fib (n-2)
Run Code Online (Sandbox Code Playgroud)

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

{-# LANGUAGE TemplateHaskell #-}
import Test
import Language.Haskell.TH
import Data.Ratio

goldRatio :: Double
goldRatio = $(litE (rationalL (toRational $ fib 21 / fib 20)))
Run Code Online (Sandbox Code Playgroud)

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

> goldRatio
1.6180339985218033
Run Code Online (Sandbox Code Playgroud)