Skip to content

Instantly share code, notes, and snippets.

@ml10
Forked from madan712/IPRangeChecker.java
Last active January 10, 2017 16:32
Show Gist options
  • Save ml10/a1a360792f3d775dfbd3da9cb0c9777a to your computer and use it in GitHub Desktop.
Save ml10/a1a360792f3d775dfbd3da9cb0c9777a to your computer and use it in GitHub Desktop.
More options for avoiding mutability in Scala
.idea
*.iml
out
target
.DS_Store
name := "oc-immutability"
scalaVersion :="2.11.8"
version :="1.0"
libraryDependencies ++= Seq(
"com.typesafe.play" %% "play-json" % "2.5.8",
"org.scalacheck" %% "scalacheck" % "1.13.2"
)
case class Course(name: String /* other fields */)
val op = (acc: String, i: Int) => s"($i + $acc)"
List(1,2,3).foldLeft("(0)")(op)
List(2,3).foldLeft("(1 + (0))")(op)
List(3).foldLeft("(2 + (1 + (0)))")(op)
List().foldLeft("(3 + (2 + (1 + (0))))")(op)
"(3 + (2 + (1 + (0))))"
val op = (i: Int, acc: String) => s"($i + $acc)"
List(1,2,3).foldRight("(0)")(op)
op(1, List(2,3).foldRight("(0)")(op))
op(1, op(2, List(3).foldRight("(0)")(op)))
op(1, op(2, op(3, List().foldRight("(0)")(op))))
op(1, op(2, op(3, "(0)")))
op(1, op(2, "(3 + (0))"))
op(1, "(2 + (3 + (0)))")
"(1 + (2 + (3 + (0))))"
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit
import scala.annotation.tailrec
object FoldExamples {
case class Item(price: BigDecimal, quantity: Int = 1 /* other fields */)
case class Order(items: List[Item] /* other fields */)
val items = List(Item(5.55), Item(3.33, 3), Item(8, 2), Item(7.75))
val order = Order(items)
val orders = List(Order(items), Order(items))
lazy val priceTotal1 = order.items.map(i => i.price * i.quantity).sum
lazy val priceTotal = order.items.foldLeft(BigDecimal(0))((acc, item) => (item.price * item.quantity) + acc)
lazy val foo = orders.flatMap(_.items.map(i => i.price * i.quantity)).sum
lazy val oof = orders.foldLeft(BigDecimal(0)) { (acc, order) =>
order.items.map(i => i.price * i.quantity).sum + acc
}
lazy val applyPriceDiscount1 = priceTotal1 > 50
lazy val applyPriceDiscount = priceTotal > 50
// compare list vs stream
lazy val stress = Stream.continually(items).flatten.take(12800000).toList
def priceTotal1Def = {
val (r, time) = timeIt(stress.map(_.price).sum)
System.out.println(s"map sum : ${time}ms")
r
}
def priceTotalDef = {
val (r, time) = timeIt(
stress.foldLeft(BigDecimal(0))(_ + _.price))
System.out.println(s"foldLeft: ${time}ms")
r
}
def timeIt[T](result: => T, unit: ChronoUnit = ChronoUnit.MILLIS): (T, Long) = {
val time = LocalDateTime.now()
(result, time.until(LocalDateTime.now(), unit))
}
sealed trait Priority extends Product with Serializable {
def priority: Int
}
object Priority {
implicit val priorityOrdering = Ordering.by[Priority, Int](_.priority)
}
case object Low extends Priority { override val priority = 0 }
case object Medium extends Priority { override val priority = 5 }
case object High extends Priority { override val priority = 10 }
case object Emergency extends Priority { override val priority = 15 }
case class Ticket(issue: String, priority: Priority /* other fields */)
object Ticket {
implicit val ordering = Ordering.by[Ticket, Priority](_.priority)
}
val newTicketQueue = List(
Ticket("Light is burned out in hallway", Low),
Ticket("Snack supply dangerously low", Medium),
Ticket("Water is leaking in the kitchen", Emergency),
Ticket("New desks need to be assembled", Medium),
Ticket("Add today's guests to security system", High))
def highestPri(tickets: List[Ticket])
(implicit ticketOrdering: Ordering[Ticket]): List[Ticket] = {
val max = tickets.max
tickets.filter(_.priority == max.priority)
}
def morePri(tickets: List[Ticket])
(implicit priorityOrdering: Ordering[Priority]): List[Ticket] = {
tickets.groupBy(_.priority).maxBy(_._1)._2
}
def highestPriorityTickets(ticketQueue: List[Ticket])
(implicit ticketOrdering: Ordering[Ticket]): List[Ticket] = {
// list z op
ticketQueue.foldRight(List.empty[Ticket]) { (ticket, highestPriority) =>
highestPriority.headOption.map { head =>
Ordering[Ticket].compare(ticket, head) match {
case lt if lt < 0 => highestPriority
case eq if eq == 0 => ticket :: highestPriority
case gt if gt > 0 => List(ticket)
}
} getOrElse List(ticket)
}
}
def mutableHighestPriority(ticketQueue: List[Ticket])
(implicit ticketOrdering: Ordering[Ticket]): List[Ticket] = {
var highestPriority = List.empty[Ticket] // z
// list op
ticketQueue.foreach { ticket =>
highestPriority = if (highestPriority.isEmpty) {
List(ticket)
} else {
val head = highestPriority.head
Ordering[Ticket].compare(ticket, head) match {
case lt if lt < 0 => highestPriority
case eq if eq == 0 => ticket :: highestPriority
case gt if gt > 0 => List(ticket)
}
}
}
highestPriority
}
val l = List(1,2,3,4,5)
l.foldRight(None: Option[Int])((i, found) => found.orElse(if (i % 3 == 1) Some(i) else None ))
def foldRight[A, B](op: (A, B) => B)(z: B)(as: Traversable[A]): B = {
as match {
case Nil => z
case x :: xs => op(x, foldRight(op)(z)(xs))
}
}
}
import scala.annotation.tailrec
// alternate, recursive implementation of foldLeft on List
@tailrec
def foldLeft[B](z: B)(op: (B, A) => B): B = {
this match {
case Nil => z
case x :: xs => xs.foldLeft(op(z, x))(op)
}
}
// alternate, recursive implementation of foldRight on List
def foldRight[B](z: B)(op: (A, B) => B): B = {
this match {
case Nil => z
case x :: xs => op(x, xs.foldRight(z)(op))
}
}
def highestPriority(ticketQueue: List[Ticket])
(implicit ticketOrdering: Ordering[Ticket]): List[Ticket] = {
// list z op
ticketQueue.foldRight(List.empty[Ticket]) { (ticket, highestPriority) =>
highestPriority.headOption.map { head =>
Ordering[Ticket].compare(ticket, head) match {
case lt if lt < 0 => highestPriority
case eq if eq == 0 => ticket :: highestPriority
case gt if gt > 0 => List(ticket)
}
} getOrElse List(ticket)
}
}
def highestPriority(tickets: List[Ticket])
(implicit priorityOrdering: Ordering[Priority]): List[Ticket] = {
tickets.groupBy(_.priority).maxBy(_._1)._2
}
def highestPriority(tickets: List[Ticket])
(implicit ticketOrdering: Ordering[Ticket]): List[Ticket] = {
val max = tickets.max
tickets.filter(_.priority == max.priority)
}
def highestPriority(ticketQueue: List[Ticket])
(implicit ticketOrdering: Ordering[Ticket]): List[Ticket] = {
var highestPriority = List.empty[Ticket] // z
// list op
ticketQueue.foreach { ticket =>
highestPriority = if (highestPriority.isEmpty) {
List(ticket)
} else {
val head = highestPriority.head
Ordering[Ticket].compare(ticket, head) match {
case lt if lt < 0 => highestPriority
case eq if eq == 0 => ticket :: highestPriority
case gt if gt > 0 => List(ticket)
}
}
}
highestPriority
}
def contains[A1 >: A](elem: A1): Boolean = {
val op = (contained: Boolean, i: A) => contained || i == elem
foldLeft(false)(op)
}
def forall(p: A => Boolean): Boolean = {
val op = (all: Boolean, i: A) => all && p(i)
foldLeft(true)(op)
}
def find[A](p: A => Boolean): Option[A] = {
val op = (found: Option[A], i: A) => found.orElse(if (p(i)) Some(i) else None)
foldLeft(None: Option[A])(op)
// Note partition on Traversable uses mutable values to work-around
// not having an addition operator, so please forgive this immutable work-around
def partition(p: A => Boolean): (Traversable[A], Traversable[A]) = {
val op = (i: A, partitioned: (Traversable[A], Traversable[A])) => {
val (trues, falses) = partitioned
if (p(i)) (Traversable(i) ++ trues, falses) else (trues, Traversable(i) ++ falses)
}
foldRight((Traversable.empty[A], Traversable.empty[A]))(op)
}
def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus)
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPRangeChecker {
public static long ipToLong(InetAddress ip) {
byte[] octets = ip.getAddress();
long result = 0;
for (byte octet : octets) {
result <<= 8;
result |= octet & 0xff;
}
return result;
}
public static boolean isValidRange(String ipStart, String ipEnd,
String ipToCheck) {
try {
long ipLo = ipToLong(InetAddress.getByName(ipStart));
long ipHi = ipToLong(InetAddress.getByName(ipEnd));
long ipToTest = ipToLong(InetAddress.getByName(ipToCheck));
return (ipToTest >= ipLo && ipToTest <= ipHi);
} catch (UnknownHostException e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
System.out.println(isValidRange("122.170.122.0", "122.170.122.255",
"122.170.122.215"));
}
}
import java.net.InetAddress
import scala.util.Try
object IPRangeCheckerFold {
def ipToLong(ip: InetAddress): Long = {
// list z op
ip.getAddress.foldLeft(0L){ (acc, octet) =>
// could also be: acc << 8 | octet & 0xff
val result = acc << 8
result | octet & 0xff
}
}
def isValidRange(ipStart: String, ipEnd: String,
ipToCheck: String): Boolean = {
Try {
val ipLo = ipToLong(InetAddress.getByName(ipStart))
val ipHi = ipToLong(InetAddress.getByName(ipEnd))
val ipToTest = ipToLong(InetAddress.getByName(ipToCheck))
ipToTest >= ipLo && ipToTest <= ipHi
}.getOrElse(false)
}
}
import java.net.InetAddress
import scala.util.Try
object IPRangeCheckerPort {
def ipToLong(ip: InetAddress): Long = {
var result = 0l // z
// list op
ip.getAddress.foreach { octet =>
result <<= 8
result |= octet & 0xff
}
result
}
def isValidRange(ipStart: String, ipEnd: String,
ipToCheck: String): Boolean = {
Try {
val ipLo = ipToLong(InetAddress.getByName(ipStart))
val ipHi = ipToLong(InetAddress.getByName(ipEnd))
val ipToTest = ipToLong(InetAddress.getByName(ipToCheck))
ipToTest >= ipLo && ipToTest <= ipHi
}.getOrElse(false)
}
}
import java.net.InetAddress
import org.scalacheck.{Gen, Properties}
import org.scalacheck.Prop.forAll
object IPRangeCheckerSpec extends Properties("IP Range") {
val ipStr: Gen[String] = Gen.listOfN(4, Gen.choose(0,255)).map(_.mkString("."))
val ipBounds: Gen[(String, String)] = {
ipStr.flatMap { ip1 =>
ipStr.map { ip2 =>
if (IPRangeCheckerFold.ipToLong(InetAddress.getByName(ip1)) >
IPRangeCheckerFold.ipToLong(InetAddress.getByName(ip2))) {
(ip2, ip1)
} else {
(ip1, ip2)
}
}
}
}
property("Converts IP Addresses Consistently Java to Scala Port") = forAll(ipBounds, ipStr) {
(ipBounds, ipToCheck) =>
val (ipStart, ipEnd) = ipBounds
IPRangeChecker.isValidRange(ipStart, ipEnd, ipToCheck) ==
IPRangeCheckerPort.isValidRange(ipStart, ipEnd, ipToCheck)
}
property("Converts IP Addresses Consistently Port to Fold") = forAll(ipBounds, ipStr) {
(ipBounds, ipToCheck) =>
val (ipStart, ipEnd) = ipBounds
IPRangeCheckerPort.isValidRange(ipStart, ipEnd, ipToCheck) ==
IPRangeCheckerFold.isValidRange(ipStart, ipEnd, ipToCheck)
}
}
def ipToLong(ip: java.net.InetAddress): Long = {
var result = 0l
ip.getAddress.foreach { octet =>
result <<= 8
result |= octet & 0xff
}
result
}
def ipToLongVerbose(ip: java.net.InetAddress): Long = {
var result = 0l
ip.getAddress.foreach { octet =>
result = result * Math.pow(2,8).toLong
result = result + (if (octet < 0) octet.toLong + 256 else octet)
}
result
}
val ipToLongCompare = (ip: java.net.InetAddress) => {
val ip1 = ip.getAddress.foldLeft(0L) { (acc, octet) =>
acc << 8 | octet & 0xff
}
val ip2 = ip.getAddress.foldLeft(0L) { (acc, octet) =>
acc * Math.pow(2,8).toLong + (if (octet < 0) octet.toLong + 256 else octet)
}
(ip1, ip2)
}
ipToLongCompare(java.net.InetAddress.getByName("172.16.0.164"))
//scala> ipToLongCompare(java.net.InetAddress.getByName("172.16.0.164"))
//res1: (Long, Long) = (2886729892,2886729892)
val ipToLongVerbose = (ip: java.net.InetAddress) => {
ip.getAddress.foldLeft(0L) { (acc, octet) =>
print(s"acc << 8 | octet & 0xff = ")
print(f"$acc%8d << 8 | $octet%3d & 0xff = ")
print(f"${acc << 8}%10d | ${octet & 0xff}%3d = ")
println(s"${acc << 8 | octet & 0xff}")
acc << 8 | octet & 0xff
}
}
ipToLongVerbose(java.net.InetAddress.getByName("172.16.0.164"))
//scala> ipToLongVerbose(java.net.InetAddress.getByName("172.16.0.164"))
//acc << 8 | octet & 0xff = 0 << 8 | -84 & 0xff = 0 | 172 = 172
//acc << 8 | octet & 0xff = 172 << 8 | 16 & 0xff = 44032 | 16 = 44048
//acc << 8 | octet & 0xff = 44048 << 8 | 0 & 0xff = 11276288 | 0 = 11276288
//acc << 8 | octet & 0xff = 11276288 << 8 | -92 & 0xff = 2886729728 | 164 = 2886729892
//res2: Long = 2886729892
case class Item(available: Int)
import play.api.libs.json.{Json, JsObject}
case class JsonIncludeValEmpty(fall: List[Course], spring: List[Course], summer: List[Course],
includeFall: Boolean, includeSpring: Boolean, includeSummer: Boolean) {
val response: JsObject = includeCourseNames(includeFall, "fall", fall) ++
includeCourseNames(includeSpring, "spring", spring) ++
includeCourseNames(includeSummer, "summer", summer)
def includeCourseNames(include: Boolean, name: String, values: List[Course]): JsObject =
if (include) {
Json.obj(
name -> Json.obj(
"list" -> Json.toJson(values.map(_.name)),
"count" -> values.length
)
)
} else {
Json.obj()
}
}
import play.api.libs.json.{Json, JsObject}
case class JsonIncludeVar(fall: List[Course], spring: List[Course], summer: List[Course],
includeFall: Boolean, includeSpring: Boolean, includeSummer: Boolean) {
val response: JsObject = {
var response: JsObject = Json.obj()
if (includeFall) {
response ++= addCourses("fall", fall)
}
if (includeSpring) {
response ++= addCourses("spring", spring)
}
if (includeSummer) {
response ++= addCourses("summer", summer)
}
response
}
def addCourses(name: String, courses: List[Course]): JsObject =
Json.obj(
name -> Json.obj(
"list" -> Json.toJson(courses.map(_.name)),
"count" -> courses.length
)
)
}
case class ListIncludeConditionalExplosion(fall: List[Course], spring: List[Course], summer: List[Course],
includeFall: Boolean, includeSpring: Boolean, includeSummer: Boolean) {
val resp = if (includeFall && includeSpring && includeSummer) {
(fall ++ spring ++ summer).map(_.name)
} else if (includeFall && includeSpring) {
(fall ++ spring).map(_.name)
} else if (includeFall && includeSummer) {
(fall ++ summer).map(_.name)
} else if (includeFall) {
fall.map(_.name)
} else if (includeSpring && includeSummer) {
(spring ++ summer).map(_.name)
} else if (includeSpring) {
spring.map(_.name)
} else if (includeSummer) {
summer.map(_.name)
} else {
List.empty
}
}
case class ListIncludeValEmpty(fall: List[Course], spring: List[Course], summer: List[Course],
includeFall: Boolean, includeSpring: Boolean, includeSummer: Boolean) {
val response: List[String] = includeCourseNames(includeFall, fall) ++
includeCourseNames(includeSpring, spring) ++
includeCourseNames(includeSummer, summer)
def includeCourseNames(include: Boolean, list: List[Course]): List[String] =
if (include) {
list.map(_.name)
} else {
List.empty
}
}
case class ListIncludeValEmptyStep1(fall: List[Course], spring: List[Course], summer: List[Course],
includeFall: Boolean, includeSpring: Boolean, includeSummer: Boolean) {
val resp: List[String] = {
val fallSubList = if (includeFall) {
fall.map(_.name)
} else {
List.empty
}
val springSubList = if (includeSpring) {
spring.map(_.name)
} else {
List.empty
}
val summerSubList = if (includeSummer) {
summer.map(_.name)
} else {
List.empty
}
fallSubList ++ springSubList ++ summerSubList
}
}
case class ListIncludeVar(fall: List[Course], spring: List[Course], summer: List[Course],
includeFall: Boolean, includeSpring: Boolean, includeSummer: Boolean) {
val response: List[String] = {
var response: List[String] = List.empty
if (includeFall) {
response ++= fall.map(_.name)
}
if (includeSpring) {
response ++= spring.map(_.name)
}
if (includeSummer) {
response ++= summer.map(_.name)
}
response
}
}
case class Store(location: String,
hours: List[String],
phoneNumber: String,
description: String,
featuredItems: List[Item])
import java.time.{DayOfWeek, LocalDate}
class StoreController {
// ...
def getAboutUs(storeId: Int): Store = {
// could be obtained from application configuration
val useDescriptionOfTheDay = true
// could be obtained from DB or cache
var store = getStore(storeId)
if (useDescriptionOfTheDay) {
store = store.copy(description = getDescriptionForDate(LocalDate.now()))
}
store
}
// ...
def getStore(id: Int): Store = {
Store("123 Fake St, Fakesville, Fakesota",
List("Su 10am - 4pm", "M-Th 8am-8pm", "Fr 8am-9pm", "Sa 9am - 9pm"),
"111-555-5523",
"Our fabulous store that sells things you didn't even know you needed!",
List(Item(1), Item(43)))
}
def getDescriptionForDate(date: LocalDate): String = {
if (date.getDayOfWeek == DayOfWeek.FRIDAY) {
"Join us at our store for a very special book signing today!"
} else {
"Come see our everyday low, low prices today!"
}
}
}
def getStore(i: Int): Store
def updateDesc(b: Boolean, s: String, st: Store): Store
def updateHolidayHours(hh: Option[List[String]], st: Store): Store
def filterFeaturedItems(i: Int, st: Store): Store
Int => Store
(Boolean, Store) => Store
(Store) => Store
(Int, Store) => Store
Int => Store
Boolean => Store => Store
Store => Store
Int => Store => Store
Int => Store
Store => Store
Store => Store
Store => Store
import java.time.LocalDate
class StoreControllerPointFree {
// ...
def getAboutUs: Int => Store = {
// could be obtained from application configuration
val useDescOfTheDay = true
val requiredAvailability = 5
getStore
.andThen(updateDesc(useDescOfTheDay))
.andThen(updateHolidayHours)
.andThen(filterFeaturedItems(requiredAvailability))
}
// ...
def updateDesc(useDescOfTheDay: Boolean): Store => Store = ???
def updateHolidayHours: Store => Store = ???
def filterFeaturedItems(requiredAvailability: Int): Store => Store = ???
def getStore: Int => Store = ???
def getDescriptionForDate(date: LocalDate): String = ???
def getHolidayHours(date: LocalDate): Option[List[String]] = ???
}
import java.time.LocalDate
class StoreControllerRefactorPhase1 {
// ...
def getAboutUs(storeId: Int): Store = {
// could be obtained from application configuration
val useDescOfTheDay = true
val requiredAvailability = 5
// could be obtained from DB or cache
val store = getStore(storeId)
val updatedStore = updateDesc(useDescOfTheDay, store)
val updatedStoreWithHolidayHours = updateHolidayHours(updatedStore)
filterFeaturedItems(requiredAvailability, updatedStoreWithHolidayHours)
}
// ...
def updateDesc(useDescOfTheDay: Boolean, store: Store): Store = {
if (useDescOfTheDay) {
store.copy(description = getDescriptionForDate(LocalDate.now))
} else {
store
}
}
def updateHolidayHours(store: Store): Store = {
getHolidayHours(LocalDate.now()).map { holidayHours =>
store.copy(hours = holidayHours)
}.getOrElse(store)
}
def filterFeaturedItems(requiredAvailability: Int, store: Store): Store = {
store.copy(featuredItems =
store.featuredItems.filter(_.available >= requiredAvailability))
}
def getStore(id: Int): Store = ???
def getDescriptionForDate(date: LocalDate): String = ???
def getHolidayHours(date: LocalDate): Option[List[String]] = ???
}
import java.time.LocalDate
class StoreControllerRefactorPhase2 {
// ...
def getAboutUs(storeId: Int): Store = {
// could be obtained from application configuration
val useDescOfTheDay = true
val requiredAvailability = 5
val storeComposed: Int => Store = (getStore _
andThen updateDesc(useDescOfTheDay)
andThen updateHolidayHours
andThen filterFeaturedItems(requiredAvailability))
storeComposed(storeId)
}
// ...
def updateDesc(useDescOfTheDay: Boolean)(store: Store): Store = ???
def updateHolidayHours(store: Store): Store = ???
def filterFeaturedItems(requiredAvailability: Int)(store: Store): Store = ???
def getStore(id: Int): Store = ???
def getDescriptionForDate(date: LocalDate): String = ???
def getHolidayHours(date: LocalDate): Option[List[String]] = ???
}
import java.time.LocalDate
class StoreControllerStory1 {
// ...
def getAboutUs(storeId: Int): Store = {
// could be obtained from application configuration
val useDescriptionOfTheDay = true
val requiredAvailability = 5
// could be obtained from DB or cache
val store = getStore(storeId)
val updatedStore = if (useDescriptionOfTheDay) {
store.copy(description = getDescriptionForDate(LocalDate.now()))
} else {
store
}
updatedStore.copy(featuredItems =
updatedStore.featuredItems.filter(_.available >= requiredAvailability))
}
// ...
def getStore(id: Int): Store = ???
def getDescriptionForDate(date: LocalDate): String = ???
}
import java.time.LocalDate
class StoreControllerStory2 {
// ...
def getAboutUs(storeId: Int): Store = {
// could be obtained from application configuration
val useDescriptionOfTheDay = true
val requiredAvailability = 5
// could be obtained from DB or cache
val store = getStore(storeId)
val updatedStore = if (useDescriptionOfTheDay) {
store.copy(description = getDescriptionForDate(LocalDate.now()))
} else {
store
}
val updatedStoreWithHolidayHours = getHolidayHours(LocalDate.now()).map { holidayHours =>
updatedStore.copy(hours = holidayHours)
}.getOrElse(updatedStore)
updatedStoreWithHolidayHours.copy(featuredItems =
updatedStoreWithHolidayHours.featuredItems.filter(_.available >= requiredAvailability))
}
// ...
def getStore(id: Int): Store = ???
def getDescriptionForDate(date: LocalDate): String = ???
def getHolidayHours(date: LocalDate): Option[List[String]] = {
if (date.getMonthValue > 10) {
Option(List("Su 9am - 6 pm", "M-Th 7am - 9pm", "Fri 7am - 10pm", "Sa 8am - 10pm"))
} else {
None
}
}
}
import java.time.LocalDate
class StoreControllerVal {
// ...
def getAboutUs(storeId: Int): Store = {
// could be obtained from application configuration
val useDescriptionOfTheDay = true
// could be obtained from DB or cache
val store = getStore(storeId)
if (useDescriptionOfTheDay) {
store.copy(description = getDescriptionForDate(LocalDate.now()))
} else {
store
}
}
// ...
def getStore(id: Int): Store = ???
def getDescriptionForDate(date: LocalDate): String = ???
}
sealed trait Priority extends Product with Serializable {
def priority: Int
}
object Priority {
implicit val priorityOrdering = Ordering.by[Priority, Int](_.priority)
}
case object Low extends Priority { override val priority = 0 }
case object Medium extends Priority { override val priority = 5 }
case object High extends Priority { override val priority = 10 }
case object Emergency extends Priority { override val priority = 15 }
case class Ticket(issue: String, priority: Priority /* other fields */)
object Ticket {
implicit val ordering = Ordering.by[Ticket, Priority](_.priority)
}
val newTicketQueue = List(
Ticket("Light is burned out in hallway", Low),
Ticket("Snack supply dangerously low", Medium),
Ticket("Water is leaking in the kitchen", Emergency),
Ticket("New desks need to be assembled", Medium),
Ticket("Add today's guests to security system", High))
val totalPrice = order.items.foldLeft(BigDecimal(0)) {
(acc, item) => (item.price * item.quantity) + acc
}
val totalPrice = order.items.map(i => i.price * i.quantity).sum
// from TraversableOnce.scala
def foldRight[B](z: B)(op: (A, B) => B): B =
reversed.foldLeft(z)((x, y) => op(y, x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment