Идиоматический способ условно обработать IO в Haskell - PullRequest
7 голосов
/ 21 апреля 2011

Я пишу небольшой скрипт на Haskell, который может принимать необязательный аргумент.Однако, если аргумент отсутствует, я хотел бы получить строку из 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.Applicative или Control.Arrow, я бы хотел знать.Я очень заинтересовался этими двумя модулями.

Спасибо!

Ответы [ 2 ]

9 голосов
/ 21 апреля 2011
main :: IO ()
main = do args <- getArgs
          name <- lowerCase <$> case args of
            [arg] -> return arg
            _     -> readPrompt "Gimme arg: "
          putStrLn name
2 голосов
/ 21 апреля 2011

Это не подходит для вашего конкретного случая использования, но название вопроса сразу заставило меня задуматься о when из Control.Monad.Прямо из документы :

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 unless аналогичным образом.

...