我试图通过编写一个简单的数学学习程序来同时学习数学和Haskell。
首先是:
出于某种原因,在祝贺功能结束后,它似乎会随机选择接下来的位置:
当试图调试问题时,我会继续按下RETURN,它会在不同的时间发生。我还添加了一些调试' print'语句。
这是程序中的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,为什么它在暂停结束后没有直接返回主页,为什么它会跳过分数过滤器。
谢谢^^
答案 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
条款的结尾会发生什么?一旦then
或else
执行完毕,就会执行then
或else
分支中不包含的内容。
所以,当你得到一些丑陋的数字时,你会开始一个递归调用,寻找更好的数字并显示它们。然后当递归调用结束时,你继续向用户显示原始的,丑陋的数字!
这里需要一个不同的控制流,比如编写一个总是返回非丑陋数字的函数,然后在你的(现在是非递归的)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