Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用GHC API评估Haskell语句/表达式_Haskell_Runtime_Evaluation_Ghc_Ghc Api - Fatal编程技术网

使用GHC API评估Haskell语句/表达式

使用GHC API评估Haskell语句/表达式,haskell,runtime,evaluation,ghc,ghc-api,Haskell,Runtime,Evaluation,Ghc,Ghc Api,对于我正在编写的工具(),我需要一种在运行时读取haskell函数定义的方法,将它们应用于我的工具中的值并检索它们的应用结果 有人能给我一个使用GHC(6.10.4或6.12.1)API的非常基本的例子吗 在运行时从文件中读取的函数定义示例: f x = 10**(4/1102*x - 1) 预期程序输出 --mapM_ print $ map f [428, 410, 389] 3.577165388142748 3.077536885227335 2.5821307011665815 !

对于我正在编写的工具(),我需要一种在运行时读取haskell函数定义的方法,将它们应用于我的工具中的值并检索它们的应用结果

有人能给我一个使用GHC(6.10.4或6.12.1)API的非常基本的例子吗

在运行时从文件中读取的函数定义示例:

f x = 10**(4/1102*x - 1)
预期程序输出

--mapM_ print $ map f [428, 410, 389]
3.577165388142748
3.077536885227335
2.5821307011665815
!!更新
我发布了一个快速的答案,但它在执行目录中创建了一个对象文件,任何避免这种情况和避免所有文件IO的提示都是最受欢迎的。我还想看到一个在内存中执行所有操作的版本:例如,用户在GUI中提供函数定义,编译/评估不会创建任何对象文件。

改编自:

f、 房协:

main.hs:

import GHC
import GHC.Paths
import DynFlags
import Unsafe.Coerce

import Control.Monad

main :: IO ()
main =
    defaultErrorHandler defaultDynFlags $ do
      func <- runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        setSessionDynFlags dflags
        target <- guessTarget "f.hs" Nothing
        addTarget target
        r <- load LoadAllTargets
        case r of
          Failed -> error "Compilation failed"
          Succeeded -> do
            m <- findModule (mkModuleName "Func") Nothing
            setContext [] [m]
            value <- compileExpr ("Func.f")
            do let value' = (unsafeCoerce value) :: Double -> Double
               return value'
      let f = func
      mapM_ print $ map f [428, 410, 389]
      return ()
导入GHC
导入GHC路径
导入动态标签
导入不安全。强制
进口管制
main::IO()
主要=
defaultErrorHandler defaultDynFlags$do

funcAPI运行得很好。我可以告诉你一些代码生成器的工作原理

GHC使用系统汇编程序创建.o文件。如果没有一个选项可以让GHC自己清理,那么您应该使用位于的bug tracker针对API提交一个功能请求。为了提交请求,您需要注册一个帐户

使用标准代码生成器,您将无法完全避免文件I/O,因为GHC将创建可重定位目标代码的工作委托给汇编程序。有一个基于LLVM的实验性后端,它可能能够在内存中完成所有操作,但如果它在6.13之前的版本中可用,我会感到惊讶。然而,在GHC开发者名单上询问可能是值得的。

使用。它是围绕GHC API的类似于GHCi的包装器,使用起来并不困难


如果您想知道它的使用示例,我在2006年第一次尝试GHC API时,它给了我很大的帮助。我真的很想看看你得到了什么答案+1@Norman拉姆齐:我刚刚发布了一个根据2008年一篇博客文章改编的答案。惊讶地发现它“正常工作”:)我想到了两个问题:1)运行解释后的代码是否可以接受?在这种情况下,您希望将API引入ghc的交互部分,而不是编译器。2) 您是否需要在受限环境中执行代码?具体来说,你需要限制对unsafePerformIO这样的东西的访问吗?@MtnViewMark:1)是的,这是可以接受的2)不一定,在我的场景中,用户在自己的计算机上运行应用程序,所以我不需要控制他们如何把东西弄得乱七八糟!setContext在最近的版本中已更改,您将需要
setContext[IIM]
import GHC
import GHC.Paths
import DynFlags
import Unsafe.Coerce

import Control.Monad

main :: IO ()
main =
    defaultErrorHandler defaultDynFlags $ do
      func <- runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        setSessionDynFlags dflags
        target <- guessTarget "f.hs" Nothing
        addTarget target
        r <- load LoadAllTargets
        case r of
          Failed -> error "Compilation failed"
          Succeeded -> do
            m <- findModule (mkModuleName "Func") Nothing
            setContext [] [m]
            value <- compileExpr ("Func.f")
            do let value' = (unsafeCoerce value) :: Double -> Double
               return value'
      let f = func
      mapM_ print $ map f [428, 410, 389]
      return ()