Implicit class for Any and/or generic type

What do people think of that:

object Foo {

  implicit class AnythingImplicits[A](a: A /* TODO: or best use Any? */) {
    def then[B](f: A =B) = f(a) // or maybe "chain"?
  }

  val studies: Seq[Study] =
    studesJsonArrayString
      .then(Json.parse)
      .then(Json.fromJson[Seq[Study]])
      .get

  // ...
}

I find it easier to use than nesting the calls, especially if I often need to comment out certain steps (I can then just comment out the relevant line in the chain). I do worry about a performance penalty though…

Thoughts anyone? Does it exist in a library somewhere?

Thanks!

EDIT: fixed code block style
EDIT2: removed noise from example

Yep, this is fine, and it’s a thing! It’s called the thrush combinator. It’s provided by scalaz and by mouse (for cats) as |>.

scala> def add1(n: Int) = n + 1
add1: (n: Int)Int

scala> def twice(n: Int) = n * 2
twice: (n: Int)Int

scala> 3 |> add1 |> twice |> add1
res1: Int = 9

You do want to use [A] in your implementation, otherwise f would need to accept Any.

Interesting, thanks! also I didn’t know about the mouse/cats libraries, so it’s good to know. I do find symbols like “|>” pretty off-putting though, I really wish they’d also offer a more explicit counterpart…

Mouse also calls it thrush and scalaz also calls it … neither is terribly enlightening.

Tracked as https://github.com/scala/bug/issues/5324

For anyone who ends up here in 2021, it looks like this is now called pipe in scala 2.13. Very glad this was added!

It’s unfortunate it requires an explicit import however, as I have ~500 calls to my then method (now thn) in my codebase. Maybe a scalac flag would be a good idea?

Another chain-like method I find really convenient is

def thnIf(test: Boolean)(f: A => A): A = if (test) f(a) else a

as used here for example.

Not perfect but you can add to your build:

scalacOptions += "-Yimports:java.lang,scala,scala.Predef,scala.util.chaining"
2 Likes

That’s a neat trick actually, will do fine for the time being. Thanks!

This is now part of my new open-source utilities library: GitHub - aptusproject/aptus-core: A utility library to help smooth certain pain points of the Java/Scala ecosystem., which I still need to formally announce (after docs are fleshed out)