Created
March 20, 2018 18:45
-
-
Save slaykovsky/e5c762b5816c0e37e0fbddfe2c57b89d 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 java.math.BigDecimal | |
import java.util.* | |
inline fun <T> Iterable<T>.sumByPrice(selector: (T) -> Price): Price { | |
return this.fold(Price.identity) { a: Price, b: T -> a + selector(b) } | |
} | |
inline fun <T> Iterable<T>.sumByWeight(selector: (T) -> Weight): Weight { | |
return this.fold(Weight.identity) { a: Weight, b: T -> a + selector(b) } | |
} | |
data class Price private constructor(private val value: BigDecimal) { | |
override fun toString() = value.toString() | |
operator fun plus(price: Price) = Price(this.value + price.value) | |
operator fun times(num: Int) = Price(this.value * BigDecimal(num)) | |
companion object { | |
val identity = Price(BigDecimal.ZERO) | |
operator fun invoke(value: BigDecimal): Optional<Price> { | |
if (value > BigDecimal.ZERO) | |
return Optional.of(Price(value)) | |
else | |
throw IllegalArgumentException("Price must be positive") | |
} | |
} | |
} | |
data class Weight private constructor(private val value: BigDecimal) { | |
override fun toString() = value.toString() | |
operator fun plus(weight: Weight) = Weight(this.value + weight.value) | |
operator fun times(num: Int) = Weight(this.value * BigDecimal(num)) | |
companion object { | |
val identity = Weight(BigDecimal.ZERO) | |
operator fun invoke(value: BigDecimal): Optional<Weight> { | |
if (value > BigDecimal.ZERO) | |
return Optional.of(Weight(value)) | |
else throw IllegalArgumentException("Weight must be positive") | |
} | |
} | |
} | |
data class Product(val name: String, val price: Optional<Price>, val weight: Optional<Weight>) | |
data class OrderLine(private val product: Product, private val count: Int) { | |
fun weight() = product.weight.get() * count | |
fun amount() = product.price.get() * count | |
} | |
object Store { | |
@JvmStatic | |
fun main(args: Array<String>) { | |
val toothPaste = Product( | |
"Tooth paste", | |
Price(BigDecimal(1.5)), | |
Weight(BigDecimal(0.5))) | |
val toothBrush = Product( | |
"Tooth brush", | |
Price(BigDecimal(3.5)), | |
Weight(BigDecimal(0.3))) | |
val orderLines = listOf( | |
OrderLine(toothPaste, 2), | |
OrderLine(toothBrush, 3) | |
) | |
val weight = orderLines.sumByWeight { it.weight() } | |
val price = orderLines.sumByPrice { it.amount() } | |
println("Total price: $price") | |
println("Total weight: $weight") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment