2016-11-14 165 views
0

我想編寫一個函數,在給定一定數量的硬幣時計算變化。除了當我真的希望輸入是Double而不是Int時,它工作得很好。將「Double」轉換爲Int

這是我的代碼

coins::[Int] 
coins = [200, 100, 50, 20, 10, 5, 2, 1] 
change::Int->[Int]->[Int] 
change n [] = [] 
change n coins 
     | n == 0 = [] 
     | n >= firstcoin = firstcoin:change (n-firstcoin) coins 
     | otherwise = change n (tail coins) 
     where firstcoin = head coins 

這工作不錯,一切,但是當我嘗試改變代碼:

change::Double->[Int]->[Int] 
     | (n*100) == 0 = [] 
     | (n*100) >= firstcoin = firstcoin:change (n-firstcoin) coins 
     | otherwise = change n (tail coins) 
     where firstcoin = head coins 

會出現以下情況:

[1 of 1] Compiling Main    (coin.hs, interpreted) 

    coin.hs:7:27: 
    Couldn't match expected type ‘Double’ with actual type ‘Int’ 
    In the second argument of ‘(>=)’, namely ‘firstcoin’ 
    In the expression: (n * 100) >= firstcoin 

    coin.hs:7:59: 
    Couldn't match expected type ‘Double’ with actual type ‘Int’ 
    In the second argument of ‘(-)’, namely ‘firstcoin’ 
    In the first argument of ‘change’, namely ‘(n - firstcoin)’ 
    Failed, modules loaded: none. 

這是像使用「/」我必須事先從整體使用?如果是這樣,這是怎麼翻譯的?

* A副作用小的問題:如何才能讓這裏寫的「嵌入式」硬幣列表進入功能,使簽名看起來像:

change::Int->[Int] 

(換句話說,我不想要明確地寫在列表中,以使其工作。我是否需要更改我的整個代碼?)

+3

處理貨幣的第一條規則之一是不使用浮點值來表示貨幣量。 – chepner

+0

請您詳細說明一下嗎?我不明白。 – Rad

+3

浮點值只是實數的近似值。你不會爲一美元的模糊部分做出改變;你修改一個確切的整數美分。 – chepner

回答

3

這次我認爲您正在尋找round。另外,我認爲你真的想要在這裏有一個新功能changeDouble,而不是修改change。這將很好地解決您的Double問題,並提供更簡單的簽名changeDouble :: Double -> [Int]

changeDouble :: Double -> [Int] 
changeDouble n = change (round (100 * n)) coins 

與混合DoubleInt問題確實是一樣的,你將通過使用/Int小號遇到的問題。


作爲一個側面說明,即使你提出更新的代碼,以change是編譯,注意遞歸調用將需要更新n - (fromIntegral firstCoin)/10而不是僅僅n - firstCoin通過。

+0

我將原來的函數改名爲改變幫助和你的建議改變,現在它效果很好!謝謝。 – Rad