surenyonjan
surenyonjan

Reputation: 2109

How to define a type of function with default value in Scala

This is slightly different from this question.

I want to define a function type that have default value defined. Like this:

trait Foo {
  type MyFunction = (Int, Option[Int] = 0) => Boolean

  def checkInts(f: MyFunction)
}

Is it possible? If yes, how can I achieve this? If not, why?

Upvotes: 1

Views: 1087

Answers (2)

Tyth
Tyth

Reputation: 1814

Read here why you can't have default arguments in anonymous functions and how to make something similar - In Scala, can you make an anonymous function have a default argument?

But if you just need a way to pass a function taking 2 or 1 argument, you can always use simpler approach:

trait Foo {
  type MyFunc1 = (Int) => Boolean
  type MyFunc2 = (Int, Int) => Boolean

  def checkInts(f: MyFunc1)
  def checkInts(f: MyFunc2)
  // common code of checkInts could be in some private method
}

Upvotes: 3

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160367

Based on my knowledge so far you cannot define a type with default parameters. A type is a type.

What you can do is define a partially applied function.

Taking as an example the following function:

scala> def factorOf(x: Int, y: Int) = y % x == 0
factorOf: (x: Int, y: Int)Boolean

If you want a shortcut to the function without retaining any parameters, you can use the wildcard operator (_) assignment

scala> val f = factorOf _
f: (Int, Int) => Boolean = <function2>

scala> val x = f(7, 20)
x: Boolean = false

If you want to retain some of the parameters, you can partially apply the function by using the wildcard operator to take the place of one of the parameters. The wildcard operator here requires an explicit type, because it is used to generate a function value with a declared input type:

scala> val multipleOf3 = factorOf(3, _: Int)
multipleOf3: Int => Boolean = <function1>

scala> val y = multipleOf3(78)
y: Boolean = true

The new function value, multipleOf3, is a partially applied function, because it contains some but not all of the parameters for the factorOf() function.

A cleaner way to partially apply functions is to use functions with multiple parameter lists. This is a technique known as currying the function:

scala> def factorOf(x: Int)(y: Int) = y % x == 0
factorOf: (x: Int)(y: Int)Boolean

scala> val isEven = factorOf(2) _
isEven: Int => Boolean = <function1>

scala> val z = isEven(32)
z: Boolean = true

Upvotes: 2

Related Questions