我可以通过评估字符串在运行时创建函数吗?

cod*_*e4j 9 haskell eval

在我解决离散数学的程序中,我想让用户输入一串逻辑运算; 例如,如果用户输入let f (x:y:_) = x && y,那么我将得到一个功能,f用于该程序的其余部分.在GHCi中,我可以通过输入轻松测试我的程序let f (x:y:_) = x && y.

我不知道如何完成这项任务.我已经evalplugins包中看了一下这个函数,但它似乎不是正确的函数.我可以在Haskell中这样做吗?

我计划使用它的代码是:

type TruthTable = [[Bool]]
type TruthTableResult = [([Bool], Bool)]

solveTable :: ([Bool] -> Bool) -> Integer -> (TruthTableResult)
solveTable f n = let table = truthTable n
                     result = map f table
                 in  zipWith (\v r -> (v, r)) table result
Run Code Online (Sandbox Code Playgroud)

Pet*_*lák 15

没有标准的Haskell函数,因为Haskell是编译的,而不是解释的.但是,有些库允许您在运行时读取和编译Haskell代码.其中一个是提示.案例示例:

import Control.Monad
import Language.Haskell.Interpreter

main = do
    -- fExpr is a Haskell code supplied by your user as a String
    let fExpr = "let f (x:y:_) = x && y in f"
    -- Create an interpreter that runs fExpr
    r <- runInterpreter $ do
            setImports ["Prelude"]
            interpret fExpr (const True :: [Bool] -> Bool)
    -- run it and get an interface to the function
    case r of
        Left err -> putStrLn $ "Ups... " ++ (show err)
        Right f  -> do
            print $ f [True, False]
            print $ f [True, True]
Run Code Online (Sandbox Code Playgroud)

这里有更多例子.

  • Common Lisp经常被编译并具有`eval`函数,因此它不是真正的参数.;) (2认同)
  • @kqr:更一般地说,根本没有这样的连接.Python和Java都为VM生成字节码,但Python有"eval",而Java没有(和Clojure,它也生成JVM字节码).OpenCL是C99,所以编译好了吧?但是我可以在运行时构造并运行一个OpenCL内核,它本质上就是"eval".等等. (2认同)
  • @kqr那是真的.我的意思是解释语言通常免费获得"eval"实现.编译的必须以某种方式包括解释器或编译器.这就是_hint_是 - 围绕GHC API的包装器. (2认同)

Don*_*art 10

您正在编写一个eval函数 - 一种运行时元编程的形式.

eval :: String -> a
Run Code Online (Sandbox Code Playgroud)

如果字符串表示Haskell程序,则必须解析字符串,键入check it,然后将其编译为目标解释器或运行时.这需要将编译器作为库访问,可以作为运行时服务(在解释器中)导出,也可以作为单独的包导出(对于编译器).

Haskell的GHC实现有几个用于对Haskell代码进行运行时评估的库:

仅当您的输入语言是Haskell时,这些适用.

如果您的输入字符串代表某种其他语言的程序,那么您正在寻找DSL解释器.这可以通过为输入语言编写自己的解释器来完成(或者如果它是一种通用语言则重用库).


Pau*_*son 5

简短的回答是Haskell没有"eval"功能,不像解释语言可以很容易地做到这一点(毕竟,他们有解释器方便且已经运行).

您可以将Haskell编译器包含在库中:请参阅http://www.haskell.org/haskellwiki/GHC/As_a_library.这是你要求的最接近的东西.

然而,听起来你不想要整个Haskell; 你真正想要的是一种不同的语言,它可能具有类似Haskell的语法,但不是整个Haskell.如果是这样,那么真正的解决方案是定义该语言并为其编写解析器.该秒差距库,启动该的地方.