9
votes

Puis-je créer une fonction à l'exécution en évaluant une chaîne?

Dans mon programme de résolution de mathématiques discrètes, je tiens à laisser entrer l'utilisateur une chaîne d'opérations logiques; par exemple, si l'utilisateur entrait Soit f (x: y: _) = x && y , alors je recevrais une fonction f pour utilisation dans le reste du programme. Dans GHCI, je peux facilement tester mon programme en saisissant Soit F (x: y: _) = x && y .

Je ne sais pas comment atteindre cette tâche. J'ai regardé dans le eval fonction du package , mais il semble ne pas être la bonne fonction. Puis-je faire cela dans HASKELLL?

Le code que je prévois d'utiliser ceci est: xxx


0 commentaires

3 Réponses :


5
votes

La réponse courte est que HASKELL n'a pas de fonction «EVAL», contrairement aux langues interprétées qui peuvent le faire assez facilement (après tout, ils ont l'interprète pratique et déjà en cours d'exécution).

Vous pouvez inclure le compilateur HASKELLL en tant que bibliothèque: voir http://www.hakell.org/hakellwiki/ghc/ As_a_library . C'est la chose la plus proche de ce que vous demandez.

Cependant, on dirait que vous ne voulez pas la totalité de HASKELL ici; Ce que vous voulez vraiment, c'est une langue différente qui peut avoir une syntaxe de type Haskell, mais n'est pas la totalité de Haskell. Si oui, la solution réelle est de définir cette langue et d'écrire un analyseur pour cela. Le Bibliothèque Parsec est l'endroit idéal pour commencer pour cela.


1 commentaires

Une autre alternative consiste à ouvrir leur programme en tant que bibliothèque et à informer les utilisateurs de saisir leurs fonctions en écrivant un programme à Haskell à l'aide de la bibliothèque OPS.



10
votes

Vous écrivez une fonction eval code> - un formulaire de métaprogramming d'exécution.

eval :: String -> a
  • via l'interprétation GHCI- Indice Li>
  • via le compilateur - Plugins li> ul>

    Celles-ci ne s'appliquent que si votre langue d'entrée est HASKELLL. p>

    Si votre chaîne d'entrée représente un programme dans une autre langue, vous recherchez un interprète DSL. Cela peut être fait en écrivant votre propre interprète pour la langue d'entrée (ou en réutilisant une bibliothèque s'il s'agit d'une langue commune). P> p>


0 commentaires

15
votes

Il n'y a pas de fonction de haskell standard, car Haskell est respecté, non interprété. Cependant, il existe des bibliothèques qui vous permettent de lire et de compiler le code HASKELL au moment de l'exécution. L'un d'entre eux est Astuce . Exemple pour votre cas:

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]


6 commentaires

La LISP commune est souvent compilée et possède une fonction eval de sorte que ce n'est pas vraiment un argument. ;)


@KQR: Plus généralement, il n'y a pas de cette connexion de ce type. Python et Java produisent Bytecode pour une machine virtuelle, mais Python a EVAL , tandis que Java ne le fait pas (et le clojure, qui produit également JVM Bytecode, fait). Opencl est C99, donc c'est compilé, non? Mais je peux construire et exécuter un noyau Opencl en runtime, ce qui est essentiellement eval . Etc.


@kqr c'est vrai. Ce que je voulais dire que les langues interprétées obtiennent généralement une implémentation eval gratuitement. Les compilées doivent en quelque sorte inclure un interprète ou un compilateur. Et c'est ce que indice est - une enveloppe autour de l'API de GHC.


@ Petrpudlák Merci pour votre réponse, cela fonctionne parfaitement pour mon programme. Je peux maintenant laisser entrer l'utilisateur la formule et obtenir la table de vérité. Cependant, je constate que le programme exécutable n'est pas un exécutable autonome, il nécessite une GHC et un indice d'exécution ...


@ Code4j Je crains que ce soit le prix de la possibilité d'exécuter une expression arbitraire Haskell. Vous pouvez essayer Plugins , mais il semble qu'il existe un problème avec des versions récentes de GHC. Une autre option serait d'écrire votre propre langue pour entrer des formules booléennes. Une langue simple consistant en une juste variables, des opérateurs booléens et des parenthèses serait assez simple à définir et à analyser en utilisant quelque chose comme Parsec.


@ code4j: pense à cela. Comment un programme Haskell va-t-il savoir comment exécuter une chaîne arbitraire sans quelque chose d'équivalent à une version complète de GHC?