Вы должны использовать Шаблон Haskell . С TH вы можете генерировать код программно, во время компиляции. В этом случае ваш модуль фактически является «шаблоном».
Например, мы можем переписать вашу программу следующим образом, чтобы вычислить вашу функцию статически. во-первых, основной код, как обычно, но вместо того, чтобы вызывать функцию модуля, он вызывает функцию, тело которой является соединением, которое будет сгенерировано во время компиляции:
{-# LANGUAGE TemplateHaskell #-}
import Table
mymodulus n = $(genmodulus 64)
main = mapM_ (print . mymodulus) [0..64]
И код для генерации таблицы статически:
{-# LANGUAGE TemplateHaskell #-}
module Table where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
genmodulus :: Int -> Q Exp
genmodulus n = return $ CaseE (VarE (mkName "n"))
[ Match (LitP (IntegerL i))
(NormalB (LitE (IntegerL (i `mod` base))))
[]
| i <- [0..fromIntegral n] ]
where
base = 10
Здесь описывается абстрактный синтаксис выражения case, который будет сгенерирован во время компиляции. Мы просто генерируем большой переключатель:
genmodulus 64
======>
case n of {
0 -> 0
1 -> 1
2 -> 2
3 -> 3
4 -> 4
...
64 -> 4 }
Вы можете увидеть, какой код генерируется с помощью -ddump-splices. Я написал код шаблона в прямом стиле. Кто-то, кто более знаком с TH, сможет упростить код шаблона.
Другой вариант - создать таблицу значений в автономном режиме и просто импортировать эту структуру данных.
Вы также можете сказать, почему вы хотите это сделать. Я полагаю, у вас очень сложная таблично-управляемая функция?