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 ?