haskell程序与另一个程序互动时挂起

问题描述 投票:0回答:1
问题

我有以下代码

--filename main.hs main :: IO () main = do loop "hello" "bye" loop :: String -> String -> IO () loop inp1 inp2 = do putStrLn $ "Type " ++ inp1 userInput <- getLine if userInput == inp1 then do putStrLn "correct answer" loop inp2 inp1 else if userInput == "exit" then do putStrLn "exiting program" return () else do loop inp1 inp2

编译后,我可以在终端中运行它,并键入命令,例如Hello Bye和Exit。该程序工作
i制作了第二个脚本,与第一个脚本

交互

--filename test_program.hs import System.IO (hPutStrLn, hFlush, hGetLine, hClose, hSetBuffering, BufferMode( NoBuffering,LineBuffering )) import System.Process (createProcess, waitForProcess, shell, proc, StdStream(CreatePipe), std_in, std_out, std_err) import Control.Monad (when) main :: IO () main = do (Just hin, Just hout, Just herr, ph) <- createProcess (shell "./main") { std_in = CreatePipe , std_out = CreatePipe , std_err = CreatePipe } hSetBuffering hin LineBuffering hSetBuffering hout NoBuffering putStrLn =<< hGetLine hout hPutStrLn hin "bla" putStrLn =<< hGetLine hout hPutStrLn hin "hello" putStrLn =<< hGetLine hout hPutStrLn hin "exit" putStrLn =<< hGetLine hout _ <- waitForProcess ph return ()

当我运行此程序时,我期望以下消息顺序

typehello

typehello

    正确答案
  1. typebye
  2. 访问程序
  3. 但什么都没有发生。如果我以以下方式重新排列代码
  4. --filename test_program.hs import System.IO (hPutStrLn, hFlush, hGetLine, hClose, hSetBuffering, BufferMode( NoBuffering,LineBuffering )) import System.Process (createProcess, waitForProcess, shell, proc, StdStream(CreatePipe), std_in, std_out, std_err) import Control.Monad (when) main :: IO () main = do (Just hin, Just hout, Just herr, ph) <- createProcess (shell "./main") { std_in = CreatePipe , std_out = CreatePipe , std_err = CreatePipe } hSetBuffering hin LineBuffering hSetBuffering hout NoBuffering hPutStrLn hin "bla" hPutStrLn hin "hello" hPutStrLn hin "exit" putStrLn =<< hGetLine hout putStrLn =<< hGetLine hout putStrLn =<< hGetLine hout putStrLn =<< hGetLine hout putStrLn =<< hGetLine hout _ <- waitForProcess ph return ()
  5. 在一开始,我将所有stdin放在命令中,然后读出stdout,我可以看到预期的消息序列。我的问题是为什么它适用于一种情况,而不是另一种情况?在我看来,如果我首先编写所有参数,然后读取输出,或者写入不应影响程序的行为。

GHC在编译程序时试图帮助您进行缓冲选择。粗略:当连接到终端时,默认情况下将把手柄延迟,以支持舒适的交互式使用,但默认情况下,这些手柄默认禁止了非终端,以支持有效的程序到程序传输。

手工选择您的缓冲以修复。
main.hs
您可能会说:“但是在

main :: IO () main = do hSetBuffering stdout LineBuffering loop "hello" "bye"

中,我已经设置了缓冲!”。不幸的是,每个程序都有自己的手柄并进行自己的缓冲。因此,您无法从内部设置
haskell stdout stdin
1个回答
0
投票
的缓冲设置。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.