我正在尝试使用Haskell的LLVM绑定来创建一个非常简单的“hello world”独立应用程序。我的想法是,当我运行我的Haskell应用程序时,它会吐出一些字节码,而这些字节码又可以运行并输出“hello world!”
-- hellofunc prints out "hello world"
hellofunc :: CodeGenModule (Function (IO ()))
_main :: (Function (IO ())) -> CodeGenModule (Function (IO ()))
_main func = createNamedFunction ExternalLinkage "main" $ do
call func
ret ()
main = writeCodeGenModule "hello.bc" (liftA _main hellofunc)
当我运行它时,我看到以下错误:
'main' function not found in module.
我正在使用main
明确创建createNamedFunction
函数。我错过了什么?
答案 0 :(得分:3)
问题在于使用liftA
或fmap
而不是=<<
。使用类型签名时,它变得更加明显(构建中断)。在liftA的情况下,_main不在CodeGenModule中进行评估,因此它不会出现在输出文件中。
修改writeCodeGenModule
以取CodeGenModule ()
代替CodeGenModule a
可能是合理的。它使LLVM JIT的用户的生活变得更复杂,但有助于防止这样的错误。
import Control.Applicative
import LLVM.Core
import LLVM.ExecutionEngine
import LLVM.Util.File
--
-- hellofunc prints out "hello world"
hellofunc :: CodeGenModule (Function (IO ()))
hellofunc = createNamedFunction ExternalLinkage "hello" $ do
ret ()
_main :: (Function (IO ())) -> CodeGenModule (Function (IO ()))
_main func = createNamedFunction ExternalLinkage "main" $ do
call func
ret ()
generateModuleBind :: CodeGenModule (Function (IO ()))
generateModuleBind = _main =<< hellofunc
-- Couldn't match expected type `Function (IO ())'
-- with actual type `CodeGenModule (Function (IO ()))'
--
-- this is the desired type:
-- generateModuleLiftA :: CodeGenModule (Function (IO ()))
--
-- but this is the actual type:
generateModuleLiftA :: CodeGenModule (CodeGenModule (Function (IO ())))
generateModuleLiftA = liftA _main hellofunc
main :: IO ()
main = writeCodeGenModule "hello.bc" generateModuleBind