Haskell:如何评估像“1 + 2”这样的字符串

时间:2011-04-07 14:43:00

标签: haskell eval

实际上我有一些类似"x + y"的公式,它是String。 我设法将x/y变量替换为"1.2"等特定值,这仍然是String类型。 现在我的表达式为"1 + 2"

所以问题是如何评估字符串类型的表达式并获得结果。

ps:我想要read,它可以直接转换整个字符串表达式,而不是逐个处理运算符(+/-等)。那可能吗?

3 个答案:

答案 0 :(得分:19)

你的问题留下了很大的解释空间。我猜你不习惯建立整个lexing,解析,类型检查和评估的整个流程。很长的答案将涉及你定义你想要评估的语言(只是用'+'整数,也许所有的理性用'+',' - ''*','/',甚至更大的语言?)并执行每个语言该语言的上述步骤。

简短的回答是:评估Haskell表达式,其中包括您可能正在讨论的基本数学运算符,只需使用“提示”包:

$ cabal install hint
...
$ ghci
> import Language.Haskell.Interpreter
> runInterpreter $ setImports ["Prelude"] >> eval "3 + 5"
Right "8"

耶!

答案 1 :(得分:5)

可能值得阅读ParsecReal World Haskell部分。您可以将其解析为表达式树,然后替换值。当您使用Parsec时,您将使用类型构建表达式树(非常粗略,我确定我犯了一些错误,我将在修复程序中编辑当人们指出他们的时候!)就像下面那样。

 data Op = Plus | Minus
 data Term = Variable String
           | Value Int
 data Expression = Expr Expression Op Expression
                 | Term

然后1 + 2将是(Expr (Variable "x") Plus (Variable "y")),您可以应用适当的替换。

为了得到结果,我猜你可以找到一个简单的函数evaluate :: Map String Int -> Expression -> Either ErrorMessage Int,它可以在地图中应用绑定,然后在可能的情况下计算结果。

答案 2 :(得分:2)

好吧,我一直在反对hint,但我现在放弃了。 我知道提示可以做到这一点,但我不确定如何。 [edit] 请参阅TomMD关于如何为提示设置导入的答案。 [/编辑]

import Language.Haskell.Interpreter (eval, runInterpreter, Interpreter, InterpreterError)

main = do let resIO = eval "3" :: Interpreter String
          res <- runInterpreter resIO
          print res

这无趣地产生Right "3"作为结果。我尝试了以下变体,只是遇到了令人困惑的错误:

... eval "3 + 3" ....
-- yields --
Left (WontCompile [GhcError (errMsg = "Not in scope: `+'"])

+运算符不在范围内??? WTF ...

import Language.Haskell.Interpreter (interpret, as, runInterpreter, Interpreter)

main = do let resIO = interpret "3" (as :: Int) :: Interpreter Int
          res <- runInterpreter resIO
          print res
-- yields --
Left (WontCompile [GhcError (errMsg = "Not in scope: type constructor or class 'Int'")])

Int类不在范围内???啊...

我邀请那些比我更有知识的人来阐述提示的细节。