Вы должны использовать Template Haskell. С помощью TH вы можете генерировать код программно, во время компиляции. В этом случае ваш mymodulus является «шаблоном».
Например, мы можем переписать вашу программу следующим образом, чтобы вычислить вашу функцию статически. первый, основной код, как обычно, но вместо вызова вашей функции модуля, он вызывает функцию, тело сплайсинг, который будет генерироваться во время компиляции:
{-# 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-сращиваний. Я написал код шаблона в прямом стиле. Кто-то, более знакомый с TH, должен иметь возможность сделать код шаблона более простым.
Другим вариантом является создание таблицы значений в автономном режиме и просто импорт этой структуры данных.
Вы также можете сказать, почему вы хотите это сделать. Я предполагаю, что у вас очень сложная функция, управляемая таблицами?
У меня есть таблица '[Integer -> Integer]'. В принципе, при задании значения генерируется новый список значений, которые были сделаны с использованием этой функции из этого списка. Я могу автоматически создавать эти списки функций. Каждый список в таблице может содержать любое количество функций. Основываясь на операции «mod», он выбирает список для использования.Но это означает, что я могу уже построить их во время компиляции. – Egon