2017-08-23 26 views
5

Tôi đang cố gắng học toán và Haskell cùng một lúc bằng cách lập trình một chương trình học toán đơn giản.Tại sao chương trình kiểm soát dòng chảy thực hiện ngẫu nhiên

Nó bắt đầu bằng:

  1. Tạo số ngẫu nhiên.
  2. Lọc các số đó để tạo sự cố dễ dàng để làm việc.
  3. Hiển thị câu hỏi rồi nhận câu trả lời của tôi
  4. Cuối cùng, nó trả lời câu trả lời chính xác cho một chức năng khác để phản hồi cho tôi ("Xin chúc mừng" - hay-- "Xin lỗi, câu trả lời đúng là BLANK .)

Đối với một số lý do, sau khi chúc mừng chức năng kết thúc, có vẻ như để lựa chọn một cách ngẫu nhiên mà nó đi tới, một trong hai:

  1. nó trở về chính (đó là những gì tôi mong đợi nó làm)
  2. Hoặc tại các vòng ngẫu nhiên, nó sẽ đi ngay lập tức đến chức năng kiểm tra toán học. Khi điều này xảy ra, bước 2 từ trên không xảy ra và tôi bắt đầu nhận được các số thập phân trong câu hỏi. Sau đó, nó có thể lặp lại bước này hoặc quay lại chính.

Khi cố gắng gỡ lỗi sự cố, tôi chỉ tiếp tục nhấn RETURN và nó sẽ xảy ra vào các thời điểm khác nhau. Tôi cũng đã thêm một số câu lệnh 'in' gỡ lỗi.

Dưới đây là 3 chức năng từ chương trình. Lưu ý rằng các cuộc gọi chính 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 "" 

Đây là đầu ra gỡ lỗi của tôi. Lưu ý rằng Thời gian duy nhất nó cung cấp các số phân số là sau khi nó không trở về chính ngay sau khi tạm dừng kết thúc.

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

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%" 

Nếu nó giúp, điều duy nhất có liên quan từ xa mà tôi đã tìm thấy cho đến thời điểm này là: Second of several forked processes does not run in Haskell .

Cuối cùng, tôi đúng ở cấp nhập cảnh của Monads nếu điều đó giúp xây dựng câu trả lời của bạn.

Tôi sẽ đánh giá cao bất kỳ trợ giúp nào có thể cho những gì đang xảy ra, id est, tại sao nó không quay trở lại chính sau khi tạm dừng kết thúc và tại sao nó bỏ qua bộ lọc số phân số.

Cảm ơn ^^

Trả lời

7

Trong funPercentOfNumberToAnother, bạn có điều khoản này:

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" 

ý định của bạn là để trở về đầu của hàm và bắt đầu lại, nếu các số là xấu xí; hoặc tiếp tục hiển thị các số cho người dùng. Điều đó hoạt động như xa như nó đi, nhưng hãy tự hỏi ... những gì sẽ xảy ra vào cuối điều khoản này if?Các nội dung không thuộc chi nhánh then hoặc else được thực hiện bất kể khi một hoặc then hoặc else được thực hiện xong.

Vì vậy, khi bạn nhận được một số số xấu xí, bạn bắt đầu một cuộc gọi đệ quy tìm kiếm số tốt hơn và hiển thị chúng. Sau đó, khi cuộc gọi đệ quy đó kết thúc, bạn cứ tiếp tục hiển thị cho người dùng số gốc, số xấu xí!

Bạn sẽ cần một luồng điều khiển khác ở đây, chẳng hạn như viết hàm luôn trả về số không xấu, và sau đó chỉ sử dụng hàm đó trong hàm (hiện tại không đệ quy) funPercentOfNumberToAnother của bạn. Hoặc bạn có thể kéo phần còn lại của phần thân của hàm, phần hiển thị số cho người dùng, vào phần else của if, để bạn không làm điều đó cho các số xấu.

0

Theo lời giải thích tuyệt vời của amalloy, tôi hiểu những gì đã xảy ra và cố định, sau đó kiểm tra vấn đề. Có mã bên ngoài câu lệnh if của:

if uglyAnswers 
    then funPercentOfNumberToAnother 
    else ... 

gây ra câu trả lời không tốt để sau này giảm tốc khi ngừng đệ quy. Vì vậy, về cơ bản tôi đã được thả lên trên chúng.

Có thể điều này có thể giải thích rõ hơn. Thấy rằng tôi có một câu trả lời rõ ràng trong lần thử đầu tiên vì vậy nó không phải trải qua quá trình đệ quy. Đối với đường đi thứ hai đã có hai cuộc gọi vì cuộc gọi đầu tiên tìm thấy một câu trả lời phân đoạn:

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

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 

Đây là khả thi đoạn mã từ câu hỏi ban đầu:

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 
Các vấn đề liên quan