Si no se conoce el tamaño de la lista de argumentos 'hasta el tiempo de ejecución, tendrá que convertir la función en algo que funcione en una lista de todos modos. Tenga en cuenta que el tipo (IORef [Word32]) significa que una acción IO leerá/escribirá una lista Word32 (mutable) durante la ejecución del programa. Los programas Haskell solo tienen que decir cómo para mutar/leer/escribir la lista, de ahí la mónada IO().
Hay un archivo examples/List.hs en el proyecto git de LLVM al que hizo referencia. Se construye una rutina de montaje LLVM "arrayLoop",
arrayLoop ::
(Phi a, IsType b,
Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i Bool) =>
Value i -> Value (Ptr b) -> a ->
(Value (Ptr b) -> a -> CodeGenFunction r a) ->
CodeGenFunction r a
arrayLoop len ptr start loopBody = do
que incrementa un puntero a una lista de enteros, p, y decrementa la longitud restante, i, en cada invocación del bloque 'cuerpo'. Ese bloque llama repetidamente 'loopBody' y almacena el resultado en 'vars', que se volvió eventual (sin tocar en cero) a 's' dentro de la función mlist:
mList ::
CodeGenModule (Function
(StablePtr (IORef [Word32]) -> Word32 -> Ptr Word32 -> IO Int32))
mList =
createFunction ExternalLinkage $ \ ref size ptr -> do
next <- staticFunction nelem
let _ = next :: Function (StablePtr (IORef [Word32]) -> IO Word32)
s <- arrayLoop size ptr (valueOf 0) $ \ ptri y -> do
flip store ptri =<< call next ref
return y
ret (s :: Value Int32)
Todo el material extra sobre nelem/NextListElement es utilizado dentro de su ejemplo para 'loopBody', que desplaza la lista una vez hacia la izquierda. Ese repositorio también menciona una lista de correo: [email protected]
GHC7 puede compilar usando LLVM, pero supongo que esto no ayudaría en un programa Haskell a interpretar un lenguaje a menos que GHC también haga compilación JIT: ¿alguien sabe si este es el caso?