How to handle Option of List in Scala?
functional-programming, monads, scala
Solution
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.
Problem
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()`: - Return None if one of the functions returns None; - Return None if `getCustomer` returns None and do not care if `getOrdersByCustomer` returns None. How would you suggest implement it?