更新时间:2023-11-10 18:58:40
问题在于使用 liftA
或 fmap
而不是 = 。当使用类型签名时,它变得更加明显(构建中断)。 _main不是在liftA情况下的CodeGenModule中计算的,所以它不会出现在输出文件中。
The problem lies in the use of liftA
or fmap
rather than =<<
. It becomes more obvious (a build break) when type signatures are used. _main is not evaluated in CodeGenModule in the liftA case, and so it doesn't appear in the output file.
修改可能是合理的, writeCodeGenModule
取得 CodeGenModule()
而不是 CodeGenModule a
。它使得LLVM JIT用户的生活变得更加复杂,但是可以帮助防止出现这种错误。
It may be reasonable to modify writeCodeGenModule
to take CodeGenModule ()
instead of CodeGenModule a
. It makes life just a bit more complicated for users of the LLVM JIT but would help prevent errors such as this one.
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