Last active
March 10, 2023 20:40
-
-
Save oisdk/569de8286f9f706749b7d0668836706a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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: