2011-04-17 11 views
12

Haskell'i yeni başlattım ve tamamen kafamı karıştırıyor. Java ve Python'u daha önce yaptığımdan çok daha anlamlı hale getirdim.Etkileşimli IO için yazma döngüleri: do-notasyonu ve düzeniyle ilgili sorunlar

Şu anda bir kullanıcı girişi almaya çalışıyorum, geçerli olup olmadığını kontrol edin, değilse: bir hata yazdırın ve girişi tekrar alın; geçerliyse: ondan bir boole değeri üretir.

Daha net olmak gerekirse, evet/hayır girdisi istiyorum, 'y' True üretecek, 'n' Yanlış üretecek ve diğer herhangi bir girdi komut satırına bir mesaj yazacak ve giriş isteğinde bulunacaktır. n tekrar.

Örn: farmiliar biçiminde yazılması

Continue? y/n: 
> assd 
Invalid input. 
Continue? y/n: 
> y 
(something happens) 
Continue? y/n: 
> n 
(Close program) 

, böyle bir işlevi: Sadece Haskell (aslında bugün) başladığından beri

boolean inputBool() { 
    while(True) { 
     str = input("Continue? y/n: "); 
     if (str == "y") { 
      return True; 
     } else if (str == "n") { 
      return False; 
     } else { 
      print("Invalid input"); 
     } 
} 

--main program-- 

while(inputBool()) { 
    doSomething(); 
} 

, ben bir fikrin pek yok ne yapabilirim ya da yapamam. Ben benzer şeyler düşünüyordum: birçok nedenden dolayı çalışmıyor Hangi

yesno :: Bool 
yesno = do 
     putStr "Continue? y/n: " 
     str <- readLn 
     if (str == "y") then True else (
      if (str == "n") then False else (
       do 
       putStrLn "Invalid input." 
       yesno 
      )  
     ) 

. Benim asıl problemim, bu "ne" nin ne yaptığını bilmem. Ben sadece io işlemleri gerektiğinde kullanılır ve bir şekilde aşağıdaki ifadeleri yürütür. Bu, haskell'de her şeyin bir değeri değerlendirdikten sonra bana mantıklı gelmiyor. "Yapmak" ne değerlendirir? Ayrıca, girinti ne bekleniyor? Rastgele bir şey gibi görünüyor. Bu işlevin, bu "yapma" işleminin kullanılmasıyla mümkün görünmeyen, boole değerine göre değerlendirmek zorunda olduğunu biliyorum. Ama sonra konsola bir şey nasıl yazdırırım ve hala True veya False olarak değerlendiren bir ifadenin bir parçası haline getirebilirim?

Yardımlarınız için teşekkür ederiz. sizin işlevi IO gerçekleştirmek için ihtiyaç yana

o kadar, IO monad bir değer döndürmesi gerekir,

+7

Belki iyi bir öğretici ile başlar: http://learnyouahaskell.com/ veya http://book.realworldhaskell.org/ –

+1

Haskell tartışmalar için en iyi forum Haskell Reddit, Haskell Stackoverflow etiketi vardır; #haskell IRC kanalı; ya da haskell-cafe @ mail listesi. –

+0

Aslında gerçekten dersler ve her şeyin uzun açıklamalarından bıktım. Programlamaya başladığımdan beri ihtiyacım olan şey sözdizimi, anahtar kelimeler, iyi bir dokümantasyon ve biraz pratikti.Bu Java ile birkaç gün içinde öğrenildi ve zaten java'yı bildiğimden beri python kolaydı. – Maro

cevap

22

(Btw. internette herhangi bir etkin haskell forumlar vardır? G/herhangi = bulamadım) onun türünün yesno :: IO Bool olması gerekir ve True ve False değerlerinin return tarafından monoya kaldırılması gerekir. Ayrıca, ham bir dize ve ayrıştırılmış bir değer istemediğinizden (bir ayrıştırma hatası potansiyeli ile birlikte) getLine yerine readLn gerekir. Son olarak, getLine numaralı telefonu aramadan önce hFlush stdout'a ihtiyacınız vardır, aksi halde komut satırında hala bir satırsonu bekler (ve bu da System.IO'yu içe aktarmanızı gerektirir).

evet her türlü/hayır soruları sormak için işlevini kullanabilirsiniz yüzden bir tartışma içine istemi dize yaptık

: Sonra

import System.IO 

yesno :: String -> IO Bool 
yesno prompt = do 
      putStr $ prompt ++ " y/n: " 
      hFlush stdout 
      str <- getLine 
      case str of 
      "y" -> return True 
      "n" -> return False 
      _ -> do 
       putStrLn "Invalid input." 
       yesno prompt 

, bir etkileşim döngü adresinin işlevini çağırabilirsiniz:

main :: IO() 
main = do 
     fun <- yesno "Is Haskell fun?" 
     if fun 
      then putStrLn "rock on" 
      else putStrLn "read more tutorials" 
     continue <- yesno "Continue?" 
     if continue then main else return() 
+0

Çok teşekkürler. Sanırım bunu anlıyorum - bu yüzden 'son' ifadesini değerlendiriyor? – Maro

+1

Temel olarak. Bir "do" bloğu, yürütme yoluna bağlı olarak bir "dönüş" tarafından üretilen değere göre değerlendirilir. –

+0

Evet, 'büyük harfle ifade' ifadesini bir büyük ifadeye yapıştırır. Tutkal operatörü (>> =) aka 'bind'dir. – pat

İlgili konular