如何使用命令行参数读取Haskell程序中的stdin?

时间:2017-06-12 17:48:43

标签: haskell command-line-arguments stdin

我知道我可以使用interact :: (String -> String) -> IO ()方便地从stdin读取并在简单的Haskell程序中写入stdout(参见http://learnyouahaskell.com/input-and-output)。

现在我想添加命令行参数来制作我的简单程序" configurable"。

有没有办法做到这一点,仍然使用interact(以便以最小的努力获得可配置的程序)?

2 个答案:

答案 0 :(得分:4)

这可以通过"排序"在使用do之前使用getArgs进行IO计算并使用interact

import System.Environment (getArgs)
main :: IO ()
main = do
    args <- getArgs
    interact (<whatever using args>)

答案 1 :(得分:2)

在大多数程序中,interact很快被替换为使用getContentsputStr。这是因为interact非常有限,因为您只能调用单个函数,并且该单个函数必须使用所有输入。随着程序复杂性的增加,您最终希望将程序分解为一次处理一段输入的较小函数,do表示法使这些函数的排序变得更加容易。

因此,为了模仿interact但也使用命令行参数,您最初可能会这样做:

import System.Environment

doStuff :: [String] -> String -> String
doStuff args input = undefined -- your code here

main :: IO ()
main = do
    args <- getArgs
    contents <- getContents
    putStr (doStuff args contents)

顺便说一下,它与:

相同
main = doStuff <$> getArgs <*> getContents >>= putStr

但稍后您可能希望添加提示,解析器或文件I / O等内容:

import System.Environment

data Arg = Taco | Boring

parseArg :: String -> Arg
parseArg arg = if arg == "taco" then Taco else Boring

doStuff :: Arg -> String -> String
doStuff Taco   input = "Yum, tacos! " ++ input
doStuff Boring input = "Meh, " ++ input

main :: IO ()
main = do
    [arg] <- map parseArg <$> getArgs
    putStr "Enter the file name: "
    fileName <- getLine
    fileContents <- readFile fileName
    writeFile ("output-" ++ fileName) (doStuff arg fileContents)