为什么程序流控制是随机执行的

时间:2017-08-23 21:46:11

标签: haskell

我试图通过编写一个简单的数学学习程序来同时学习数学和Haskell。

首先是:

  1. 生成随机数。
  2. 过滤这些数字以创建一个易于使用的问题。
  3. 显示问题然后接受我的回答
  4. 最后,它将我的答案和正确答案交给另一个函数给我反馈(a&#34;祝贺&#34; - 或 - &#34;抱歉,正确的答案是BLANK)。< / LI>

    出于某种原因,在祝贺功能结束后,它似乎会随机选择接下来的位置:

    1. 返回(这是我期望它做的)。
    2. 或者在随机循环中,它会立即进入数学测试功能。发生这种情况时,上面的第2步不会发生,我开始在问题中获得小数。然后它可以重复此步骤或返回主要
    3. 当试图调试问题时,我会继续按下RETURN,它会在不同的时间发生。我还添加了一些调试&#39; print&#39;语句。

      这是程序中的3个功能。请注意,main调用funPercentOfNumberToAnother:

      funPercentOfNumberToAnother :: IO ()
      funPercentOfNumberToAnother = do
          (percentDec, percentStr) <- getPercent
          ofNum <- getDecimal (200 :: Decimal)
          let isNum = percentDec * ofNum
          if uglyAnswers ([ofNum, isNum], [percentDec])
              then do
                  putStrLn ("ofNum: " ++ show ofNum)
                  putStrLn ("isNum: " ++ show isNum)
                  putStrLn "___________________________"
                  funPercentOfNumberToAnother
              else do
                  putStrLn ("ofNum: " ++ show ofNum)
                  putStrLn ("isNum: " ++ show isNum)
                  putStrLn "Percents"
          -- putStrLn "\n\n"
          putStrLn (show isNum ++ " is what percent of " ++ show ofNum ++ "?\n" )
          putStr "> "
          ans <- getLine
          submitStringAnswer (ans, percentStr ++ "%")
      
      submitStringAnswer :: (String, String) -> IO ()
      submitStringAnswer (myAns, correctAns) = do
          if myAns == correctAns
              then putStrLn "Congratz!"
              else do
                  putStrLn ("Sorry the correct answer is: " ++ show correctAns)
          pause
      
      
      pause :: IO ()
      pause = do
          x <- getLine
          putStrLn ""
      

      这是我的调试输出。请注意,它只给出小数的唯一时间是在暂停结束后不立即返回主页。

           __  __       _   _                          _   _         
          |  \/  | __ _| |_| |__   ___ _ __ ___   __ _| |_(_) ___ ___ 
          | |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
          | |  | | (_| | |_| | | |  __/ | | | | | (_| | |_| | (__\__ 
          |_|  |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/
      
      1.) Learn Math
      2.) Math Lookup
      3.) Quit Excolo
      
      1
      ofNum: 35
      isNum: 15.75
      ___________________________
      ofNum: 120
      isNum: 102
      Percents
      102 is what percent of 120?
      
      > 
      Sorry the correct answer is: "85%"
      
      
      15.75 is what percent of 35?
      
      > 
      Sorry the correct answer is: "45%"
      
      
      
           __  __       _   _                          _   _         
          |  \/  | __ _| |_| |__   ___ _ __ ___   __ _| |_(_) ___ ___ 
          | |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
          | |  | | (_| | |_| | | |  __/ | | | | | (_| | |_| | (__\__ 
          |_|  |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/
      
      1.) Learn Math
      2.) Math Lookup
      3.) Quit Excolo
      
      1
      ofNum: 80
      isNum: 44
      Percents
      44 is what percent of 80?
      
      > 
      Sorry the correct answer is: "55%"
      
      
      
           __  __       _   _                          _   _         
          |  \/  | __ _| |_| |__   ___ _ __ ___   __ _| |_(_) ___ ___ 
          | |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
          | |  | | (_| | |_| | | |  __/ | | | | | (_| | |_| | (__\__ 
          |_|  |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/
      
      1.) Learn Math
      2.) Math Lookup
      3.) Quit Excolo
      
      1
      ofNum: 15
      isNum: 2.25
      ___________________________
      ofNum: 60
      isNum: 0.6
      ___________________________
      ofNum: 40
      isNum: 30
      Percents
      30 is what percent of 40?
      
      > 
      Sorry the correct answer is: "75%"
      
      
      0.6 is what percent of 60?
      
      > 
      Sorry the correct answer is: "1%"
      
      
      2.25 is what percent of 15?
      
      > 
      Sorry the correct answer is: "15%"
      

      如果它有帮助,我迄今为止发现的唯一远程相关的是Second of several forked processes does not run in Haskell

      最后,如果这有助于制定你的答案,我就在Monads的入门级别。

      我很感激任何人都可以提供任何有关发生的事情的帮助,id est,为什么它在暂停结束后没有直接返回主页,为什么它会跳过分数过滤器。

      谢谢^^

2 个答案:

答案 0 :(得分:7)

funPercentOfNumberToAnother中,您有以下条款:

if uglyAnswers ([ofNum, isNum], [percentDec])
    then do
        putStrLn ("ofNum: " ++ show ofNum)
        putStrLn ("isNum: " ++ show isNum)
        putStrLn "___________________________"
        funPercentOfNumberToAnother
    else do
        putStrLn ("ofNum: " ++ show ofNum)
        putStrLn ("isNum: " ++ show isNum)
        putStrLn "Percents"

如果数字很丑,你的意图是回到功能的开头并重新开始;或以其他方式继续向用户显示数字。这样做可行,但问问自己......这个if条款的结尾会发生什么?一旦thenelse执行完毕,就会执行thenelse分支中不包含的内容。

所以,当你得到一些丑陋的数字时,你会开始一个递归调用,寻找更好的数字并显示它们。然后当递归调用结束时,你继续向用户显示原始的,丑陋的数字!

这里需要一个不同的控制流,比如编写一个总是返回非丑陋数字的函数,然后在你的(现在是非递归的)funPercentOfNumberToAnother函数中使用它。或者你可以将函数体的其余部分(向用户显示数字的部分)拉到else的{​​{1}}部分,这样就不会对丑陋的数字执行此操作

答案 1 :(得分:0)

根据amalloy的重要解释,我理解发生了什么并修复了,然后测试了这个问题。代码在if语句之外:

if uglyAnswers
   then funPercentOfNumberToAnother
   else ...

导致错误的答案,以便在递归停止后逐渐降低。所以基本上我一直在储备它们。

也许这可以更好地解释它。看到我在第一次尝试时得到了一个干净的答案,所以它不必经历递归。对于第二次去,有两个电话,因为第一个电话找到了一个小部分答案:

     __  __       _   _                          _   _         
    |  \/  | __ _| |_| |__   ___ _ __ ___   __ _| |_(_) ___ ___ 
    | |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
    | |  | | (_| | |_| | | |  __/ | | | | | (_| | |_| | (__\__ 
    |_|  |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/

1.) Learn Math
2.) Math Lookup
3.) Quit Excolo

1
In the else statement
===================================
Finally outside the else statement
ofNum: 10
isNum: 4

     __  __       _   _                          _   _         
    |  \/  | __ _| |_| |__   ___ _ __ ___   __ _| |_(_) ___ ___ 
    | |\/| |/ _` | __| '_ \ / _ \ '_ ` _ \ / _` | __| |/ __/ __|
    | |  | | (_| | |_| | | |  __/ | | | | | (_| | |_| | (__\__ 
    |_|  |_|\__,_|\__|_| |_|\___|_| |_| |_|\__,_|\__|_|\___|___/

1.) Learn Math
2.) Math Lookup
3.) Quit Excolo

1
Bad answer alert!
===================================
In the else statement
===================================
Finally outside the else statement
ofNum: 160
isNum: 80
===================================
Finally outside the else statement
ofNum: 55
isNum: 0.55

以下是原始问题的可行代码段:

funPercentOfNumberToAnother :: IO ()
funPercentOfNumberToAnother = do
    (percentDec, percentStr) <- getPercent
    ofNum <- getDecimal (200 :: Decimal)
    let isNum = percentDec * ofNum
    if uglyAnswers ([ofNum, isNum], [percentDec])
        then funPercentOfNumberToAnother
        else do
            let message = show isNum ++ " is what percent of " ++ show ofNum ++ "?\n"
            testProblem (percentStr ++ "%", message)


testProblem :: (String, String) -> IO ()
testProblem (correctAns, message) = do
    putStrLn message
    putStrLn "\n\n"
    putStr "> "
    myAns <- getLine
    if myAns == correctAns
        then putStrLn "Congratz!"
        else do
            putStrLn ("Sorry the correct answer is: " ++ show correctAns)
    pause