0

Say we have an object (e.g. a list) in Scala, and we want to sequence user-defined functions with object member functions, for instance:

g(l.map(f)
   .foldRight(...))
 .map(h)

If the sequence of functions is larger, the code gets a little messy. Is there a better way to write such a code? Maybe something like:

l.map(f)
 .foldRight(...)
 .call(g)   // call would simply call function g on the resulting object
 .map(h)
Matei
  • 152
  • 1
  • 5
  • 1
    Is really a shame `pipe` has to be imported, just for that I almost never use it. – Luis Miguel Mejía Suárez Mar 30 '23 at 13:14
  • 1
    take a look at the implementation if you use and older scala version and want to implement your own `pipe`: https://github.com/scala/scala/blob/2.13.x/src/library/scala/util/ChainingOps.scala – gatear Mar 30 '23 at 14:08
  • 1
    @LuisMiguelMejíaSuárez `scalacOptions += "-Yimports:java.lang,scala,scala.Predef,scala.util.chaining"` (AFAIK works in 2.13 and 3). – Mateusz Kubuszok Mar 31 '23 at 07:53
  • @MateuszKubuszok that only makes my code not copyable to other projects without **sbt** tinkering. I don't even do that for **cats** stuff that I import in every file, I won't for an operator that I need every blue moon. – Luis Miguel Mejía Suárez Mar 31 '23 at 13:33
  • 1
    Technically, virtually half the things that you do on corporate projects make code "non-copyable": adding own build-tool plugin with custom options, internal company's artifactory, custom Predef/preludes with own types and aliases, renaming things on import, enabling kind projector syntax or Scala 3 cross-compile compatibility... Though personally, I almost never need to copy-paste tons of things from one projects to another. If I'd need to do that often I would consider turning that functionality into a library. YMMV – Mateusz Kubuszok Mar 31 '23 at 15:24
  • @MateuszKubuszok so what I mean with copyable is being able to create a **Scatie** or a bug report and making ti reproducible, or being able to read some code, understand it, and apply something similar in another place. Sure, adding libraries technically breaks that but that is impossible to avoid, other than that, I never add custom Predefs and the like. – Luis Miguel Mejía Suárez Mar 31 '23 at 15:34
  • @LuisMiguelMejíaSuárez then we're clearly operate under difference constraints: my contracts so far made it a fireable offense to share any employers's code, be it on GitHub, StackOverflow or Scastie, so every single repro I've ever written were made from scratch and useless for anything other than the bug report. I had no reason to use the same requirements for my production code as my bug report code. ¯\_(ツ)_/¯ – Mateusz Kubuszok Mar 31 '23 at 17:10

1 Answers1

2

Using scala.util.chaining._ you can re-write

trait A
trait B
trait C
trait D
trait E
val l:  List[A]      = ???
val f:  A => B       = ???
val z:  C            = ???
val op: (B, C) => C  = ???
val g:  C => List[D] = ???
val h:  D => E       = ???
g(l.map(f)
  .foldRight(z)(op))
.map(h)

as

import scala.util.chaining._

l.map(f)
  .foldRight(z)(op)
  .pipe(g)
  .map(h)

https://github.com/scala/scala/blob/v2.13.10/src/library/scala/util/ChainingOps.scala

https://blog.knoldus.com/new-chaining-operations-in-scala-2-13/

https://alvinalexander.com/scala/scala-2.13-pipe-tap-chaining-operations/

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66