2016-09-28 33 views
0

其他控制流,我有以下簡單的數字猜測程序清理,如果在Haskell

import System.Random 

turn :: Int -> Int -> Int -> IO() 
turn number attempt attempts = 
    do 
    if attempts == 0 
     then putStrLn "You lose" 
     else if attempt==number 
       then putStrLn "You got it!" 
       else if attempt==0 
         then guess number attempt attempts 
       else if attempt < number 
         then do 
          putStrLn "The number is greater" 
          guess number attempt attempts 
       else 
         do 
         putStrLn "The number is lesser" 
         guess number attempt attempts 

guess :: Int -> Int -> Int -> IO() 
guess number attempt attempts = 
    do 
    putStr "Try and guess number " 
    g <- getLine 
    let number' = read g :: Int 
    let check = (number'==number) 
    let attempts' = if check then attempts else attempts - 1 
    turn number number' attempts' 

numberGuess :: IO() 
numberGuess = do 
    let attempts = 5 
    number <- randomRIO (0, 10) :: IO Int 
    turn number 0 attempts 

我如何收拾醜陋的if else或者什麼技術是在Haskell可用?

+0

您可能還會看看'-XMultiWayIf'語法擴展。 https://downloads.haskell.org/~ghc/7.6.2/docs/html/users_guide/syntax-extns.html#multi-way-if – Schoon

回答

7

您最外層的doturn實際上並沒有做任何事情。所以你應該尼克斯。接下來,使用模式匹配和警衛來開始清理事情。

turn _number _attempt 0 = putStrLn "You lose" 
turn number attempt attempts 
    | attempt == number = putStrLn "You got it!" 
    | attempt == 0 = guess number attempt attempts 
    | attempt < number = do 
     putStrLn "The number is greater" 
     guess number attempt attempts 
    | otherwise = do 
     putStrLn "The number is lesser" 
     guess number attempt attempts 

最後一步清理turn會分解出模式「做一些事情,然後調用guess」。我會讓你自己嘗試。我用第一種情況的模式匹配來證明這種技術,這種技術往往是正確的。在這種情況下,使用警衛可能會更好。

對於guess,簡單的一點就是合併一些表達式。

guess :: Int -> Int -> Int -> IO() 
guess number attempt attempts = do 
    putStr "Try and guess number " 
    g <- getLine 
    let attempts' = if read g == number 
        then attempts 
        else attempts - 1 
    turn number number' attempts' 

但是請注意,這read一般不宜用來處理用戶的輸入,因爲它會崩潰壞輸入你的程序。或許,導入Text.Read並使用readMaybe