import Foundation | |
protocol Currency { static var sign: String { get } } | |
enum GBP: Currency { static let sign = "£" } | |
enum EUR: Currency { static let sign = "€" } | |
enum USD: Currency { static let sign = "$" } | |
protocol _Money { | |
associatedtype C: Currency | |
var amount: NSDecimalNumber { get } | |
} | |
struct Money<Cur: Currency>: _Money, CustomStringConvertible, FloatLiteralConvertible, IntegerLiteralConvertible { | |
typealias C = Cur | |
let amount: NSDecimalNumber | |
var description: String { return Cur.sign + String(amount) } | |
init(floatLiteral value: Double) { self.amount = NSDecimalNumber(double: value) } | |
init(integerLiteral value: Int) { self.amount = NSDecimalNumber(integer: value) } | |
init(_ amount: NSDecimalNumber) { self.amount = amount } | |
} | |
extension _Money where C == GBP { | |
var gbp: Money<GBP> { return Money(amount) } | |
var eur: Money<EUR> { return Money(amount.decimalNumberByMultiplyingBy(1.27)) } | |
var usd: Money<USD> { return Money(amount.decimalNumberByMultiplyingBy(1.44)) } | |
} | |
extension _Money where C == EUR { | |
var gbp: Money<GBP> { return Money(amount.decimalNumberByMultiplyingBy(0.79)) } | |
var eur: Money<EUR> { return Money(amount) } | |
var usd: Money<USD> { return Money(amount.decimalNumberByMultiplyingBy(1.13)) } | |
} | |
extension _Money where C == USD { | |
var gbp: Money<GBP> { return Money(amount.decimalNumberByMultiplyingBy(0.69)) } | |
var eur: Money<EUR> { return Money(amount.decimalNumberByMultiplyingBy(0.88)) } | |
var usd: Money<USD> { return Money(amount) } | |
} | |
let fivePound: Money<GBP> = 5 // £5 | |
let threeEuro: Money<EUR> = 3 // €3 | |
print(fivePound.eur) // €6.35 | |
print(threeEuro.gbp) // £2.37 |
This comment has been minimized.
This comment has been minimized.
Thanks @oisdk for the initial solution and @davedelong for optimizing it! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
This approach requires n² conversion methods, which is grossly inefficient. Also, you shouldn't be doing formatting manually in the
description
method. Here's a slightly different approach to address those two issues: