Reputation: 4132
I am new to functional programming in Scala and am working on a module where each operators (class instance/object) are chained together. The operators has only one function and that returns a Try[T]. I'm looking for a more readable way of chaining them together.
trait Mapper {
def map(in: T): Try[T]
}
trait Reducer {
def reduce(in: T): Try[T]
}
trait Grouper {
def group(in: T, batchSize: int): Try[T]
}
Lets just say I have created the implementations for these traits. Now in my main function, I can do something like
object MyApp extends App {
val mapper: Mapper = ...
val reducer: Reducer = ...
val grouper: Grouper = ...
def run(): Try[Unit] = {
val inp: T = ...
mapper.map(inp) match {
case Success(x) => reducer.reduce(x) match {
case Success(y) => grouper.group(x) match {
case Success(z) => ..// some other function call
case Failure(e) => throw e
}
case Failure(e) => throw e
}
case Failure(e) => throw e
}
}
run()
}
Is there a way, I can avoid all these Success, Failure pattern matching and do it in a better way?
Upvotes: 2
Views: 488
Reputation: 4063
Simple and typical for-comprehension
is the case:
def run(): Try[Unit] = {
val inp: T = ...
for {
mapResult <- mapper.map(inp)
reduceresult <- reducer.reduce(mapResult)
groupResult <- grouper.group(x)
} yield ()
}
You can find lot's of learning materials about this topic in internet, but essentially this is syntax sugar over flatMap
, map
, withFilter
and foreach
for cases like yours.
Upvotes: 5