是否有可能在Haskell中"读取"一个函数?

asg*_*451 9 haskell

新用户,半noobie Haskell程序员在这里.我一直在寻找"在48小时内自己编写一个方案",我发现虽然在实践中它会非常不安全,但看看Haskell程序是否可以"读取"一个函数会很有趣.

例如,read "+" :: Num a => a -> a -> a - (即(+)的类型)

但是,上面的例子不起作用.有任何想法吗?我知道在实践中这是一个非常愚蠢的事情,但如果有可能的话会很酷,对吧?

mar*_*iop 11

Haskell是一种静态编译语言,您可以使用Language.Haskell.Interpreter将字符串解释为函数.

读取具有类型的二进制函数的最小示例Int -> Int -> Int是:

import Language.Haskell.Interpreter
import System.Environment (getArgs)

main :: IO ()
main = do
  args <- getArgs
  -- check that head args exists!
  errorOrF <- runInterpreter $ do
    setImports ["Prelude"]
    interpret (head args) (as::Int -> Int -> Int)
  case errorOrF of
    Left errs -> print errs
    Right f   -> print $ f 1 2
Run Code Online (Sandbox Code Playgroud)

你可以用这种方式调用这个程序(这里我假设代码的文件名是test.hs):

> ghc test.hs
...
> ./test "\\x y -> x + y"
3
Run Code Online (Sandbox Code Playgroud)

该程序的核心是runInterpreter,即解释器解释String的地方.我们首先Prelude使用setImports将模块添加到上下文中以使其可用,例如,该+函数.然后我们调用explain来将第一个参数解释为函数,并使用as Int -> Int -> Int来强制执行该类型.结果runInterpreter是一个Either InterpretError a地方a是你喜欢的类型.如果结果是Left你有错误,否则你有你的功能或价值.从中提取后Right,可以在使用Haskell函数时使用它.f 1 2例如,见上文.

如果你想要一个更完整的例子,你可以检查haskell-awk,这是我和gelisam项目实现一个类似awk的命令行实用程序,它使用Haskell代码而不是AWK代码.我们Language.Haskell.Interpreter用来解释用户功能.