IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Haskell Discussion :

Exécuter du code Haskell en ligne de commande ( via Pipes , Ghcid ou autre ? )


Sujet :

Haskell

  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2014
    Messages : 34
    Points : 20
    Points
    20
    Par défaut Exécuter du code Haskell en ligne de commande ( via Pipes , Ghcid ou autre ? )
    Bonsoir,

    J’aimerais disposer d'une petite application qui permettrait d’exécuter des commande Haskell en ligne de commande ( depuis terminal shell ) et d’en afficher les résultats ( et cela sans ouvrir une cession ghci standard ).

    Pour être plus clair, en voici un code qui fait presque ce que je cherche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {-# LANGUAGE OverloadedStrings #-}
     
    module Main where
     
    import System.Process.Streaming -- from process-streaming
    import Pipes (lift,yield) -- from pipes
    import System.Posix.Env.ByteString (getArgs)
    import Control.Concurrent (threadDelay)
     
     
    main :: IO ()
    main = do
      info <- getArgs
      let command = head info
     
      executeInteractive (shell "ghci"){ std_in = CreatePipe } (feedProducer (yield command))

    Résultat ( après compilation ) : dans terminal

    ~ /Users/Main [1..7]


    produit

    1. GHCi, version 8.0.2: http://www.haskell.org/ghc/ for help
    2. Prelude> [1,2,3,4,5,6,7]
    3. Prelude> Leaving GHCi.


    Pas mal ! Mais le problème est qu'après ' leaving GHCi ' es affectations précédentes sont perdues,
    comme le montre l'expérience suivante :

    étape 1:

    ~ /Users/Main x=7

    1. GHCi, version 8.0.2: http://www.haskell.org/ghc/ for help
    2. Prelude> Prelude> Leaving GHCi.

    étape 2:

    ~ /Users/Main x

    1. GHCi, version 8.0.2: http://www.haskell.org/ghc/ for help
    2. Prelude>
    3. <interactive>:1:1: error: Variable not in scope: x
    4. Prelude> Leaving GHCi


    Peut-on éviter cette fermeture automatique de la connexion avec GHCI ?

    J’ai installé GHcid
    et essayé le code suivant ( qu’on trouve à la première réponse proposée ici )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import Language.Haskell.Ghcid
     
    main :: IO ()
    main = do 
        (g, _) <- startGhci "ghci" (Just ".") True 
        let executeStatement = exec g
        executeStatement "let x = 33"
        executeStatement "x + 8" >>= print . head
        executeStatement "print x" >>= print . head
        stopGhci g

    Le problème est que startGhci a pour type

    startGhci :: String -> Maybe FilePath -> (Stream -> String -> IO ()) -> IO (Ghci, [Load])

    Donc la valeur booléenne True comme troisième argument ( à la ligne 5 ) n’a pas de sens.
    Comme je ne connais rien du type (Stream -> String -> IO ()) je ne sais pas quoi mettre à la place...

    Dommage, car j’imagine qu’en combinant startGhci avec getArgs comme précédemment, je devrais pouvoir maintenir une pipe ouverte pour une série de dialogues avec GHCI avant de la fermer avec stopGhci.

    Est-ce possible ? Y a-t-il d’autres solutions ?

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : avril 2003
    Messages : 6 245
    Points : 8 560
    Points
    8 560
    Par défaut
    Cet exemple utilisait sans-doute une vieille version de Ghcid. Voici ce que la doc actuelle dit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    startGhci :: String -> Maybe FilePath -> (Stream -> String -> IO ()) -> IO (Ghci, [Load])
     
    Start GHCi, returning a function to perform further operation, as well as the result of the initial loading. If you do not call stopGhci then the underlying process may be leaked. The callback will be given the messages produced while loading, useful if invoking something like "cabal repl" which might compile dependent packages before really loading.
    Le "callback" est la fonction passée comme troisième argument, ce terme est employé parce que cette fonction est passée pour pouvoir être rappelée ("callbackée...") par la suite durant l'exécution de Ghci. C'est un terme standard pour une fonction passée en argument dans cet objectif. Ici on te dit que cette fonction sera appelée lorsque Ghci essaye de charger un module et on lui donnera Stream (soit Stdout, soit Stderr selon que le message a été émis normalement ou comme une erreur) et une String contenant le message du chargement. Donc cette fonction est là au cas où tu souhaiterais réagir de façon personnalisée à un problème au chargement (ou simplement indiquer que tels et tels modules ont été chargés).

    Autrement dit pour l'instant tu peux probablement ignorer ces messages sans problème et simplement fournir une fonction qui ne fait rien avec eux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    startGhci "ghci" (Just ".") (\_ _-> return ())

  3. #3
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2014
    Messages : 34
    Points : 20
    Points
    20
    Par défaut
    En effet, l'exemple sur lequel je me m'étais basé ( bien présent sur plusieurs sites ) n'était pas récent.
    (\_ _-> return ()) comme troisième argument de startGhci donne le résultat souhaité.

    Merci beaucoup.
    Bertrand

Discussions similaires

  1. Exécuter un script PHP en ligne de commande
    Par sami_c dans le forum Unix
    Réponses: 4
    Dernier message: 09/05/2009, 15h28
  2. exécution de fichier sql en ligne de commande
    Par orchidee_07 dans le forum MySQL
    Réponses: 2
    Dernier message: 12/03/2009, 13h19
  3. Réponses: 2
    Dernier message: 31/10/2008, 10h39
  4. Réponses: 9
    Dernier message: 30/08/2006, 13h51
  5. Réponses: 1
    Dernier message: 26/07/2006, 11h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo