In scala, what's the idiomatic way to apply a series of composed functions to a value?

StackOverflow https://stackoverflow.com/questions/20574426

  •  01-09-2022
  •  | 
  •  

Question

What's the more idiomatic way to write the following?

val starting_value = ...
val result1 = f1(startingValue)
val result2 = f2(result1)
...
val resultN = fN(resultN-1)

If starting_value were a list of items to which I wanted to apply these functions, I could write

starting_list.map(f1).map(f2)...map(fN)

I can fake this by doing something like

Some(starting_value).map(f1)....map(fN).get

or

List(starting_value).map(f1)....map(fN).head

but this seems unnecessarily confusing.

Note: This question seems related but seems to be about a downstream issue.

Was it helpful?

Solution

(f1 andThen f2 andThen ... fN) {
  startingValue
}

OTHER TIPS

Use the forward pipe operator. For example (for def f(s: String) = s.length):

scala> "abc" |> f |> 0.until
res16: scala.collection.immutable.Range = Range(0, 1, 2)

You can find it in Scalaz, but you can find its definition elsewhere as well.

You can define an extension class that is also a value class. A value class is a special Scala construct that wraps up a single value inside a new compile-time type but the same exact runtime object, thus avoiding any new memory allocation. The class would look like:

implicit class Piper[A](val x: A) extends AnyVal {
  def |>[B](f: A => B) = f(x)
}

Now when you do:

startingValue |> f1 |> f2 |> ... |> fN

Scala implicitly wraps up the starting value and each intermediate value in a Piper object at compile time and applies the Piper object's |> method, passing the intermediate values forward. At runtime no extra memory or time costs are incurred.

via /u/Baccata64

You could as well consider wrapping you value into Try, and then applying map(fN) on it. Then you will have prove, that if any function will fail, you won't get unexpected exception. You can then match on Success/Failure and do some recovery or just printing exact failure.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top