开发者

Idiomatic way to conditionally process IO in Haskell

I'm writing a little shell script in Haskell which can take an optional argument. However, if the argument is not present, I'd like to get a line from stdin in which to ask for a value.

What would be the idiomatic way to do this in 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

Oh, and if there's a way to do it with something from Control.Applicative or 开发者_开发知识库Control.Arrow I'd like to know. I've become quite keen on these two modules.

Thanks!


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


This doesn't fit your specific use case, but the question title made me think immediately of when from Control.Monad. Straight from the docs:

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

Conditional execution of monadic expressions.

Example:

main = do args <- getArgs
          -- arg <- something like what FUZxxl did..
          when (length args == 1) (putStrLn $ "Using command line arg: " ++ arg)
          -- continue using arg...

You can also use when's cousin unless in similar fashion.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜