2016-11-14 142 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