Haskell расширил определенные thunks во время компиляции?
Есть ли способ заставить Haskell расширять определенные thunks во время выполнения. Например, скажем, у меня есть
--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 на данный момент.
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