如果参数列表的大小直到运行时才知道,则无论如何您都需要将该函数转换为在列表上运行的内容。请注意,(IORef [Word32]) 类型意味着 IO 操作将在程序执行期间读/写(可变)Word32 列表。Haskell 程序只需要说明如何改变/读取/写入列表——因此就有了 IO() monad。
您引用的 LLVM git 项目中有一个 Examples/List.hs 文件。它构造了一个 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
Run Code Online (Sandbox Code Playgroud)
在每次调用“body”块时,都会增加指向整数 p 列表的指针,并减少剩余长度 i。该块重复调用“loopBody”并将结果存储在“vars”中,最终返回(零不变)到 mList 函数内的“s”:
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)
Run Code Online (Sandbox Code Playgroud)
有关 nelem/NextListElement 的所有额外内容都在其“loopBody”示例中使用,它将列表向左移动一次。该存储库还提到了一个邮件列表:haskell-llvm@projects.haskellorg。
GHC7 可以使用 LLVM 进行编译,但我想这对解释语言的 Haskell 程序没有帮助,除非 GHC 也进行 JIT 编译 - 有人知道是否是这种情况吗?