簡體   English   中英

在 Haskell 中將 25 美分、10 美分和便士轉換為美元和美分

[英]Converting quarters, dimes, and pennies to dollars and cents in Haskell

我正在嘗試將 25 美分、10 美分和便士轉換為美元和美分,但我似乎無法運行代碼。

我試過這段代碼:

-- Declaration
toCents :: Int -> Int -> Int -> Int
toDollar :: Int -> Int -> Int -> Int

-- Definition
toCents quarter dime penny  = quarter*25 + dime*10 + penny
toDollar quarter dime penny = (toCents quarter dime penny) / 100) - ((toCents quarter dime penny mod 100) / 100)

main :: IO()
main = do
 let quarter = 12
 let dime = 67
 let penny = 43
 let sumDollar = toDollar quarter dime penny
 let sumCents = toCents quarter dime penny - (toDollar quarter dime penny) * 100
 print ("Conversion of " ++ show quarter ++ " quarters, " ++ show dime ++ " dimes, and " ++ show penny ++ " pennies to dollars and cents:")
 print(sumDollar ++ " dollars and " ++ sumCents ++ " cents.")

它導致了這個錯誤:

[1 of 1] Compiling Main             ( main.hs, main.o )
main.hs:7:68: error:
    • Couldn't match expected type ‘(Integer -> Integer -> Integer)
                                    -> Integer -> Int’
                  with actual type ‘Int’
    • The function ‘toCents’ is applied to five arguments,
      but its type ‘Int -> Int -> Int -> Int’ has only three
      In the first argument of ‘(/)’, namely
        ‘(toCents quarter dime penny mod 100)’
      In the second argument of ‘(-)’, namely
        ‘((toCents quarter dime penny mod 100) / 100)’
  |
7 | toDollar quarter dime penny = (toCents quarter dime penny / 100) - ((toCents quarter dime penny mod 100) / 100)
  |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
main.hs:17:8: error:
    • Couldn't match expected type ‘[Char]’ with actual type ‘Int’
    • In the first argument of ‘(++)’, namely ‘sumDollar’
      In the first argument of ‘print’, namely
        ‘(sumDollar ++ " dollars and " ++ sumCents ++ " cents.")’
      In a stmt of a 'do' block:
        print (sumDollar ++ " dollars and " ++ sumCents ++ " cents.")
   |
17 |  print(sumDollar ++ " dollars and " ++ sumCents ++ " cents.")
   |        ^^^^^^^^^
main.hs:17:40: error:
    • Couldn't match expected type ‘[Char]’ with actual type ‘Int’
    • In the first argument of ‘(++)’, namely ‘sumCents’
      In the second argument of ‘(++)’, namely ‘sumCents ++ " cents."’
      In the second argument of ‘(++)’, namely
        ‘" dollars and " ++ sumCents ++ " cents."’
   |
17 |  print(sumDollar ++ " dollars and " ++ sumCents ++ " cents.")
   |                   

表達式toCents quarter dime penny mod 100被解析為

     ((((toCents quarter) dime) penny) mod) 100

或者

      ( ( ( (toCents quarter
            ) dime
          ) penny
        ) mod
      ) 100

這看起來很奇怪,但如果你記住柯里化是如何工作的,它並沒有那么奇怪:它對應於,在一種非柯里化語言中,

      toCents(quarter, dime, penny, mod, 100)

這當然仍然是無稽之談:您將mod作為參數提供給 function toCents ,而不是將其用作運算符。 帶有字母名稱的中綴運算符必須寫在反引號中才能應用它們,例如37`mod`4 ,與mod 37 4相同。 中綴運算符總是綁定弱於前綴 function 應用程序,所以如果你寫了

  toCents quarter dime penny `mod` 100

那么這將被解析為

  mod (toCents quarter dime penny) 100

這可能是你想要的。 然而,這並不意味着它適合這項任務。 你在做什么

    foo/100 - (foo`mod`100)/100

是實現簡單舍入到負數 integer 除法的非常迂回的嘗試。

它在 Python 中有點工作,但即使在那里它也沒有真正做它應該做的事情:Python 自動將整數foo100轉換為浮點數以執行除法,然后相互減去浮點數,結果仍然是浮點數它恰好有零小數部分。

Haskell 甚至不允許這種混亂發生:它會抱怨/運算符在整數上不可用。 你真的想要那個,你必須明確地轉換為浮點數。

但是您希望這樣:您應該簡單地使用內置的 integer 除法運算符

toDollar quarter dime penny = toCents quarter dime penny `div` 100

...假設它真的應該有舍入到消極的行為。

更好的方法是正確構建代碼和數據,這將避免冗余計算和神秘的Int -> Int ->...簽名:

data DollarValue = DollarValue {
       dollarPartVal, centPartVal :: Int
     }
data DollarCoins = DollarCoins {
       quarterCoinCount, dimeCoinCount, pennyCoinCount :: Int
     }

coinsValue :: DollarCoins -> DollarValue
coinsValue (DollarCoins q d p) = DollarValue dollars cents
 where (dollars, cents) = (25*q + 10*d + p)`divMod`100

import Text.Printf

main = do
   let quarter = 12
       dime = 67
       penny = 43
   let DollarValue sumDollars sumCents
        = coinsValue $ DollarCoins quarter dime penny
   printf
    "Conversion of %i quarters, %i dimes, and %i pennies: %i dollars and %i cents.\n"
                   quarter      dime          penny       sumDollars     sumCents

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM