I’m trying to use streamly-process to communicate with some REPL in background. It could be Python or anything but here I try to run GHCi. I came up with the following code :
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import Data.Word
import qualified Streamly.Data.Stream.Prelude as Stream
import qualified Streamly.Data.Fold.Prelude as Fold
import qualified Streamly.System.Process as Process
import qualified Streamly.Console.Stdio as Stdio
import qualified Streamly.Data.Array.Foreign as Array
-- When using Stream.fromList, it works ! To do so, uncomment the following :
-- Stream.fromList["putStrLn "This works ! "n", " 3 + 4n"]
</code>
<code>import Data.Word
import qualified Streamly.Data.Stream.Prelude as Stream
import qualified Streamly.Data.Fold.Prelude as Fold
import qualified Streamly.System.Process as Process
import qualified Streamly.Console.Stdio as Stdio
import qualified Streamly.Data.Array.Foreign as Array
stringToByteArray :: String -> Array.Array Word8
stringToByteArray = Array.fromList . map (fromIntegral . fromEnum)
-- a version of getLine that does not ignore the newline character.
getNewLn :: IO String
getNewLn = fmap (++ "n") getLine
main :: IO ()
main = do
Stream.fold (Fold.takeEndBy ( == stringToByteArray "Leaving GHCi.") Stdio.writeChunks) $
Process.pipeChunks "ghci" [] $
fmap stringToByteArray $
Stream.repeatM getNewLn
-- When using Stream.fromList, it works ! To do so, uncomment the following :
-- Stream.fromList ["putStrLn "This works ! "n", " 3 + 4n"]
</code>
import Data.Word
import qualified Streamly.Data.Stream.Prelude as Stream
import qualified Streamly.Data.Fold.Prelude as Fold
import qualified Streamly.System.Process as Process
import qualified Streamly.Console.Stdio as Stdio
import qualified Streamly.Data.Array.Foreign as Array
stringToByteArray :: String -> Array.Array Word8
stringToByteArray = Array.fromList . map (fromIntegral . fromEnum)
-- a version of getLine that does not ignore the newline character.
getNewLn :: IO String
getNewLn = fmap (++ "n") getLine
main :: IO ()
main = do
Stream.fold (Fold.takeEndBy ( == stringToByteArray "Leaving GHCi.") Stdio.writeChunks) $
Process.pipeChunks "ghci" [] $
fmap stringToByteArray $
Stream.repeatM getNewLn
-- When using Stream.fromList, it works ! To do so, uncomment the following :
-- Stream.fromList ["putStrLn "This works ! "n", " 3 + 4n"]
When I use fromList, it works as expected and returns :
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>GHCi, version 9.8.2: https://www.haskell.org/ghc/ :? for help
ghci>This works !
ghci>7
ghci> Leaving GHCi.
</code>
<code>GHCi, version 9.8.2: https://www.haskell.org/ghc/ :? for help
ghci> This works !
ghci> 7
ghci> Leaving GHCi.
</code>
GHCi, version 9.8.2: https://www.haskell.org/ghc/ :? for help
ghci> This works !
ghci> 7
ghci> Leaving GHCi.
However, when I’m using getNewLn this is what I get :
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>GHCi, version 9.8.2: https://www.haskell.org/ghc/ :? for help
ghci> I'm typing
the return key
several times
but nothing happens ...
</code>
<code>GHCi, version 9.8.2: https://www.haskell.org/ghc/ :? for help
ghci> I'm typing
the return key
several times
but nothing happens ...
</code>
GHCi, version 9.8.2: https://www.haskell.org/ghc/ :? for help
ghci> I'm typing
the return key
several times
but nothing happens ...
What did I get wrong ?
haskell
streamly
The input is getting buffered on the input side of pipeChunks. Once there is sufficient amount of input collected in the buffer it will be actually sent to the process (ghci here). It can be solved by applying line buffering in the pipeChunks implementation.