Haskell: cómo evaluar una cadena como “1 + 2”

En realidad, tengo una fórmula como "x + y" , que es una String . Logré reemplazar la variable x/y con valores específicos como "1.2" , que sigue siendo String tipo de String . Ahora tengo una expresión como "1 + 2" .

Entonces, el problema es cómo evaluar una expresión de un tipo de cadena y obtener el resultado.

ps: Quiero algo así como read , que puede convertir directamente la expresión de cadena completa en lugar de manejar el operador (+/-, etc.) caso por caso. ¿Es eso posible?

Su pregunta deja mucho espacio para la interpretación. Supongo que no está acostumbrado a construir una línea completa de lexings, análisis sintácticos, tal vez verificación de tipos y evaluación. La respuesta larga implicaría definir qué idioma desea evaluar (solo enteros con ‘+’, quizás todos los racionales con ‘+’, ‘-‘ ‘* *’, ‘/’, o incluso un lenguaje más grande?) Y realice cada uno de los pasos anteriores para ese idioma.

La respuesta corta es: para evaluar las expresiones de Haskell, que incluyen los operadores matemáticos básicos de los que probablemente estés hablando, solo usa el paquete “sugerencia”:

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

¡Hurra!

Puede valer la pena leer la sección de Parsec de Real World Haskell . Podrías analizarlo en un árbol de expresiones y luego sustituirlo por los valores. Al usar Parsec crearías un árbol de expresiones usando tipos (muy aproximadamente, estoy seguro de que cometí algunos errores que editaré en arreglos) ¡cuando y como la gente los señale!) como la siguiente.

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

Entonces 1 + 2 sería (Expr (Variable "x") Plus (Variable "y")) y podría aplicar las sustituciones apropiadas.

Para obtener el resultado, supongo que podrías corregir una función simple evaluate :: Map String Int -> Expression -> Either ErrorMessage Int que aplicaría los enlaces en el mapa y luego calcula el resultado si es posible.

Bueno, he estado golpeando mi cabeza contra la indirecta, pero me rindo por ahora. Sé que puedo hacer esto pero no estoy seguro de cómo. [edit] Consulte la respuesta de TomMD sobre cómo configurar las importaciones para obtener sugerencias. [/editar]

 import Language.Haskell.Interpreter (eval, runInterpreter, Interpreter, InterpreterError) main = do let resIO = eval "3" :: Interpreter String res <- runInterpreter resIO print res 

Esto produce de manera poco interesante el Right "3" como resultado. Intenté las siguientes variantes, solo para encontrar errores desconcertantes:

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

El operador + no está en el 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'")]) 

La clase Int no está en el scope ??? ugh ...

Invito a aquellos más conocedores que yo a exponer los detalles más finos de la pista.