Rad
Rad

Reputation: 141

"Converting" Double to Int

I want to write a function that calculates change when given an amount of coins. It has worked great except when I actually want the input to be a Double rather than Int.

This is my code

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

This works nice and all, but when I try changing the code to:

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

The following happens:

  [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.

Is this like using "/" where I have to use fromIntegral beforehand? If so, how does that translate here?

*A little side question: how can I make the list of coins written here "embedded" into the function so that the signature would look like:

change::Int->[Int]

(in other words, I don't want to explicitly write in the list for it to work. Would I need to change my whole code?)

Upvotes: 1

Views: 3907

Answers (1)

Alec
Alec

Reputation: 32309

This time I think you are looking for round. Also, I think you really do want a new function changeDouble here, not to modify change. This will solve your Double problem nicely and presents the simpler signature changeDouble :: Double -> [Int].

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

The problem with mixing Double and Int is indeed the same as you would encounter via use of / on Ints.


As a side note, even if your proposed updated code to change were to compile, note that the recursive call would need to be updated to pass in n - (fromIntegral firstCoin) / 10 instead of just n - firstCoin.

Upvotes: 3

Related Questions