Pattern Matching with Function Patterns

Hello.
I’ ve defined two functions with type (Int, Int) => (Int) as follows:

def add(x: Int, y: Int): Int = x + y
def subtract(x: Int, y: Int): Int = x -y

Now I would like to define a HOF which should determine if I’m passing add or subtract; i.e.,

def testFun(x: Int, y: Int, f: (Int, Int) => Int) = f match {
  case add(a, b) => x
  case subtract(a,b) => y
}

But the compiler complains that:

scala> def testFun(x: Int, y: Int, f: (Int, Int) => Int) = f match {
     | 
     |   case add(a, b) => x
     | 
     |   case subtract(a,b) => y
     | 
     | }
         case add(a, b) => x
              ^
On line 3: error: not found: value add
         case subtract(a,b) => y
              ^
On line 5: error: not found: value subtract

I’ve tried also

def funTest: (Int, Int) => Int = {
  case add(x, y) => x
  case subtract(x, y) => y
}

but with the same result.
Any idea?

Anything you define with def is a method, not a function and not a value. It only so happens that the compiler sometimes wraps a method into a function value (i.e. lifts the method into a function) when a function value is needed.

To do matching, you need some real named values, i.e. object or val. Also, x and y are not fields, so you cannot match for them. You can do:

object TestApp {
object add extends ((Int, Int) => Int) {
override def apply(x: Int, y: Int): Int = x+y
}
object subtract extends ((Int, Int) => Int) {
override def apply(x: Int, y: Int): Int = x-y
}
def testFun(x: Int, y: Int, f: (Int, Int) => Int): Int = f match {
case add => x + y
case subtract => x - y
}
}

or

object TestApp {
val add: ((Int, Int) => Int) = (x: Int, y: Int) => x + y
val subtract: ((Int, Int) => Int) = (x: Int, y: Int) => x - y
def testFun(x: Int, y: Int, f: (Int, Int) => Int): Int = f match {
case add => x + y
case subtract => x - y
}
}

3 Likes

Thank you @curoli. I should have thought of that.

i just liltle confuse, what do you need
here’s some general approach which may help you :

sealed trait Operations
case class Add() extends Operations
case class Subtract() extends Operations


def testFun(x: Int, y: Int, f: Operations) = f match {
 case Add() => x + y
 case Subtract() => x - y
}


testFun(2, 3, Add())

OR

def add(x: Int, y: Int): Int = x + y
def subtract(x: Int, y: Int): Int = x - y


def testFun(x: Int, y: Int, f: (Int, Int) => Int) = f(x, y)

testFun(3, 7, add)