在Haskell中有条件地处理IO的惯用方法

时间:2011-04-21 10:40:17

标签: haskell coding-style io conditional command-line-arguments

我在Haskell中编写了一个小shell脚本,可以使用可选参数。但是,如果参数不存在,我想从stdin中获取一行来请求一个值。

在Haskell中执行此操作的惯用方法是什么?

#!/usr/bin/env runhaskell

import Control.Applicative ((<$>))
import Data.Char (toLower)
import IO (hFlush, stdout)
import System.Environment (getArgs)

main :: IO ()
main = do args <- getArgs
          -- here should be some sort of branching logic that reads
          -- the prompt unless `length args == 1`
          name <- lowerCase <$> readPrompt "Gimme arg: "
          putStrLn name

lowerCase = map toLower

flushString :: String -> IO ()
flushString s = putStr s >> hFlush stdout

readPrompt :: String -> IO String
readPrompt prompt = flushString prompt >> getLine

哦,如果有办法用Control.ApplicativeControl.Arrow我想知道的话。我对这两个模块非常热衷。

谢谢!

2 个答案:

答案 0 :(得分:9)

main :: IO ()
main = do args <- getArgs
          name <- lowerCase <$> case args of
            [arg] -> return arg
            _     -> readPrompt "Gimme arg: "
          putStrLn name

答案 1 :(得分:2)

这不适合您的特定用例,但问题标题让我立即想到来自when的{​​{1}}。直接从the docs

  

Control.Monad

     

有条件执行monadic表达式。

示例:

when :: Monad m => Bool -> m () -> m ()

您也可以类似的方式使用main = do args <- getArgs -- arg <- something like what FUZxxl did.. when (length args == 1) (putStrLn $ "Using command line arg: " ++ arg) -- continue using arg... 的堂兄when