Debe utilizar Template Haskell. Con TH puede generar código programáticamente, en tiempo de compilación. Su mymodulus es efectivamente una "plantilla" en este caso.
Por ejemplo, podemos reescribir su programa de la siguiente manera, para calcular su función estáticamente. En primer lugar, el código principal, como de costumbre, pero en lugar de llamar a su función de módulo, se llama a una función cuyo cuerpo es un empalme que se generará en tiempo de compilación:
{-# LANGUAGE TemplateHaskell #-}
import Table
mymodulus n = $(genmodulus 64)
main = mapM_ (print . mymodulus) [0..64]
Y el código para generar la tabla de forma estática:
{-# 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
Esto describe la sintaxis abstracta de la expresión de caso, que se generará en tiempo de compilación. Simplemente, generamos un gran cambio:
genmodulus 64
======>
case n of {
0 -> 0
1 -> 1
2 -> 2
3 -> 3
4 -> 4
...
64 -> 4 }
Se puede ver qué código se genera con -ddump-empalmes. He escrito el código de la plantilla en estilo directo. Alguien más familiarizado con TH debería ser capaz de simplificar el código de patrón.
Otra opción sería generar una tabla de valores fuera de línea e importar esa estructura de datos.
También podría decir por qué desea hacer esto. ¿Supongo que tiene una función muy compleja basada en tablas?
Tengo una tabla de '[Entero -> Entero]'. Básicamente eso, dado un valor, genera una nueva lista de valores que se han hecho usando esa función de esa lista. Puedo construir esas listas de funciones automáticamente. Cada lista en la tabla puede contener cualquier cantidad de funciones. Básicamente, basado en una operación 'mod', elige una lista para usar.Pero eso significa que ya puedo construirlos en tiempo de compilación. – Egon