如果在haskell中控制流量,则清理

时间:2016-09-28 06:18:15

标签: 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

我如何清理丑陋的如果在haskell中可用的其他方法或技术?

1 个答案:

答案 0 :(得分:7)

do中最外面的turn实际上并没有做任何事情。所以你应该把它搞定。接下来,使用模式匹配和警卫来开始清理。

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,也许。