"转换"加倍到

时间:2016-11-14 19:57:09

标签: haskell functional-programming

我想写一个函数,在给定一定数量的硬币时计算变化。除非我真的希望输入是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.

这就像使用" /"我必须事先在整体上使用?如果是这样,那怎么翻译?

*一个小问题:如何制作这里写的硬币清单"嵌入式"进入函数,使签名看起来像:

change::Int->[Int]

(换句话说,我不想在列表中明确写入它才能工作。我需要更改我的整个代码吗?)

1 个答案:

答案 0 :(得分: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