gpt4 book ai didi

haskell - 在 haskell 中从 stdin 读取的正确方法

转载 作者:行者123 更新时间:2023-12-02 21:18:40 25 4
gpt4 key购买 nike

我有一个程序,根据给定的参数以不同的方式工作:

  • 如果有 2 个参数 - 它采用第二个参数作为文件名,从中读取,然后简单地将其打印出来。
  • 如果有 1 个参数 - 它从 stdin 读取并打印出来。

代码如下:

main :: IO ()
main = do

-- Read given arguments
args <- getArgs

-- If file containing gramma was given
if length args == 2 then do
hfile <- openFile (last args) ReadMode
content <- hGetContents hfile
let inGramma = getGramma content
doJob (head args) inGramma
hClose hfile
return ()

-- If no file was given - reads from stdin
else if length args == 1 then do
content <- getContents
let inGramma = getGramma content
doJob (head args) inGramma
return ()

else do putStrLn "Invalid count of arguments!"

问题是,当它从标准输入读取时,在每一个新行(按下输入键)之后,它都会打印该行,然后读取下一个。我需要它等待整个输入然后将其打印出来(在 Ctrl+D 之后)。

以下是该代码中使用的函数:

-- | Structure of gramma
data GrammaStruct = Gramma
{ nonTerminals :: NonTerminals
, terminals :: Terminals
, start :: Start
, rules :: Rules
} deriving (Eq)

-- | Representation of gramma
instance Show GrammaStruct where
show (Gramma n t s r) =
init (showSplit n) ++
"\n" ++ init (showSplit t) ++
"\n" ++ showStart s ++
"\n" ++ init (showRules r)

-- | Print gramma
showGramma :: GrammaStruct -> IO ()
showGramma gr = do
putStrLn $ show gr

-- | Transforms string given from file of stdin into gramma representation in app
getGramma :: String -> GrammaStruct
getGramma hIn = procLns (lines hIn)

-- | Depending on option given, provides required functionality
doJob :: String -> GrammaStruct -> IO ()
doJob op gramma
| op == "-i" = showGramma gramma

谢谢。

最佳答案

这里的问题是 getContents 使用惰性 IO,使得输入流被逐行处理。如果您想在开始执行作业之前强制它读取整个输入,您可以使用以下技巧:

...
if length args == 1 then do
content <- getContents
length content `seq` return () -- force the input to be fully read now
let inGramma = getGramma content
doJob (head args) inGramma
return ()

或者,使用evaluate,或者在Hackage中查找提供严格getContents的严格IO模块。例如,我刚刚发现 strict-io 包提供 System.IO.Strict.getContents 。使用它你应该能够编写(未经测试)

import qualified System.IO.Strict as S
...
if length args == 1 then do
content <- run S.getContents
...

关于haskell - 在 haskell 中从 stdin 读取的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29060916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com