Russell
Russell

Reputation: 2076

Scala function combination with generics

I want to combine 2 Scala functions into a 3rd with andThen but am running into problems with the type system.

Here is the code:

object Test{

  def process1[T](in : List[T]) : List[T] = in

  def process2[T](in : List[T]) : List[T] = in

  //this works fine but you have to read it inside out
  def combined2[T](in : List[T]) : List[T] = process2(process1(in))

  //this also works but at the cost of creating a new function every time
  def combined3[T](in : List[T]) : List[T] = {
    (process1[T] _ andThen process2[T] _)(in)
  }

  //this doesn't work. it is a function List[Nothing] => List[Nothing]
  val combined = process1 _ andThen process2 _

  def main(s : Array[String]) {
    val input : List[Int] = List(1,2,3)
    val out1 : List[Int] = process1(input)

    val combinedOut2 : List[Int] = combined2(input)

    val combinedOut3 : List[Int] = combined3(input)

    //this will not compile as combined is [List[Nothing] => List[Nothing]
    //val combinedOut : List[Int] = combined(input)
  }
}

Is there a nice way to get the value of combined to be a function from List[T] to List[T] or is this a fundamental problem with type erasure?

Upvotes: 0

Views: 176

Answers (2)

Milind
Milind

Reputation: 1

You can combine functions this way, it's more cleaner

implicit class FunctionCombiner[T, U](fn: T => U) {
    def &&&(f: T => U): T => U = {
        (t: T) => {
            fn(t); f(t)
        }
    }
}

After this you can run statements like:

val f1 = (i: Int) => println((1*i).toString)
val f2 = (i: Int) => println((2*i).toString)
val f3 = (i: Int) => println((3*i).toString)

val f = f1 &&& f2 &&& f3

f(5)

This produces result:

5
10
15

Upvotes: 0

serega
serega

Reputation: 564

Not sure if it's nice, but combined3 can be shortened to:

def combined3[T] = process1[T] _ andThen process2[T] _

Creation of function instances every time may be optimized for each case:

val combinedInt = combined3[Int]

combinedInt(input)

Upvotes: 1

Related Questions