9

Suppose I have two functions f and g:

val f: (Int, Int) => Int = _ + _
val g: Int => String = _ +  ""

Now I would like to compose them with andThen to get a function h

val h: (Int, Int) => String = f andThen g

Unfortunately it doesn't compile :(

scala> val h = (f andThen g)
<console> error: value andThen is not a member of (Int, Int) => Int
   val h = (f andThen g)

Why doesn't it compile and how can I compose f and g to get (Int, Int) => String ?

DNA
  • 42,007
  • 12
  • 107
  • 146
Michael
  • 41,026
  • 70
  • 193
  • 341
  • 2
    Possible duplicate of [Why doesn't Function2 have an andThen method?](https://stackoverflow.com/questions/21680117/why-doesnt-function2-have-an-andthen-method) – theon May 30 '17 at 09:54

2 Answers2

13

It doesn't compile because andThen is a method of Function1 (a function of one parameter: see the scaladoc).

Your function f has two parameters, so would be an instance of Function2 (see the scaladoc).

To get it to compile, you need to transform f into a function of one parameter, by tupling:

scala> val h = f.tupled andThen g
h: (Int, Int) => String = <function1>

test:

scala> val t = (1,1)
scala> h(t)
res1: String = 2

You can also write the call to h more simply because of auto-tupling, without explicitly creating a tuple (although auto-tupling is a little controversial due to its potential for confusion and loss of type-safety):

scala> h(1,1)
res1: String = 2
Community
  • 1
  • 1
DNA
  • 42,007
  • 12
  • 107
  • 146
7

Function2 does not have an andThen method.

You can manually compose them, though:

val h: (Int, Int) => String = { (x, y) => g(f(x,y)) }
Michael Zajac
  • 55,144
  • 7
  • 113
  • 138