2011-04-21 16 views
7

Haskell'de isteğe bağlı bir argüman alabilen küçük bir kabuk betiği yazıyorum. Ancak, argüman mevcut değilse, bir değer istemek için stdin'den bir hat almak istiyorum.Haskell'de IO koşullu olarak işlenmenin deyimsel yolu

Haskell'de bunu yapmanın deyimsel yolu ne olurdu?

#!/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, ve bilmek istiyorum Control.Applicative veya Control.Arrow bir şey ile bunu yapmanın bir yolu olup olmadığını. Bu iki modüle oldukça meraklıyım.

Teşekkürler!

cevap

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

Bunu beğendim. Oldukça temiz. Vaka ifadesindeki modeller kapsamlı değildir, ancak kolayca düzeltilebilir. –

+0

@ Ionuț G. Stan: Anlamınızı tek tek tercüme ediyorum. Örüntüyü kapsamlı hale getirmek, örneğimin daha az temiz olmasını sağlar. – fuz

+0

Alt satırda, "case args" in önüne "lowerCase <$>" ifadesini koydum, böylece komut satırı argümanı da küçültülecekti. Ayrıca, istenen davranışı daha yakın kalmak için sadece [arg] 've' _' yerine [[] 'yerine) eşleştirebilirsiniz. –

1

Bu özel kullanım uygun düşmez, ama soru başlık bana Control.Monad hemen when düşündürdü. Düz the docs den: monadik ifadelerin

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

Koşullu yürütme.

Örnek:

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

Ayrıca benzer şekilde when 'ın kuzeni unless kullanabilirsiniz.

+0

Ben de ne zaman düşündüm. Mesele şu ki, sadece bir if/o yerine bir çeşit/o/else'a ihtiyacım vardı. Ayrıca, ne zaman bir şey döndürmezse. İçinde "bir değişkeni atamak" gerekirdi, ki bu muhtemelen Eyalet monadını kullanmak anlamına gelirdi. Yine de öyle değil. Cevap için teşekkürler. –

İlgili konular