Suppose I have a function getCustomers
and getOrdersByCustomer
.
def getCustomer():List[Customer] = ... def getOrdersByCustomer(cust: Customer): List[Order] = ...
Now I can easily define a function getOrdersOfAllCustomers
def getOrdersOfAllCustomers(): List[Order] = for(cust <- getCustomer(); order <- getOrderByCustomer(cust)) yield order
So far, so good but what if getCustomer
and getOrdersByCustomer
return Options of the lists ?
def getCustomer():Option[List[Customer]] = ... def getOrdersByCustomer(cust: Customer): Option[List[Order]] = ...
Now I would like to implement two different flavors of getOrdersOfAllCustomers()
:
getCustomer
returns None and do not care if getOrdersByCustomer
returns None.How would you suggest implement it?
I think you should consider three possibilities--a populated list, an empty list, or an error--and avoid a lot of inelegant testing to figure out which one happened.
So use Try
with List
:
def getOrdersOfAllCustomers(): Try[List[Order]] = {
Try(funtionReturningListOfOrders())
}
If all goes well, you will come out with a Success[List[Order]]
; if not, Failure[List[Order]]
.
The beauty of this approach is no matter which happens--a populated list, an empty list, or an error--you can do all the stuff you want with lists. This is because Try
is a monad just like Option
is. Go ahead and filter
, forEach
, map
, etc. to your heart's content without caring which of those three occurred.
The one thing is that awkward moment when you do have to figure out if success or failure happened. Then use a match
expression:
getOrdersOfAllCustomers() match {
case Success(orders) => println(s"Awww...yeah!")
case Failure(ex) => println(s"Stupid Scala")
}
Even if you don't go with the Try
, I implore you not to treat empty lists different from populated lists.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With