How do you define a type for a function in Scala?

To augment the original answer:

For some more complex cases, you can go with structural types that could also include function definitions [1], [2].

As for particular examples and practical usage, function types could be used quite nicely with Futures, e.g. to pass an ExecutionContext and actually execute an async function after you pass it.

Note, however, if you always have your EC available in the executing class and therefore you have no need to pass it, you could go with by-name arguments ("gimme just a Future result") [3].

A draft example below shows this simple idea: it has a function type just with the ec and a structural type that could also take some parameters for the function to be executed. It also shows an alternative with by-name function:

/** Define types in companion and sample functions that use them as args. */
class Fun(implicit ec: ExecutionContext) {
  import Fun._

  def foo(fun: SimplyFun): Future[String] = fun()
  def bar(fun: StructuredFun): Future[String] = fun.buzz(fun.bee)
  def byNameBaz(fun: => Future[String]) = fun
}

object Fun {
  type SimplyFun = ExecutionContext => Future[String]
  type StructuredFun = {
    def buzz(bee: Int)(implicit ec: ExecutionContext): Future[String]
    val bee: Int
  }
}

// (somewhere outside)
// example args could be instantiated as follows:
val simpleArg: SimplyFun = _ => Future.successful(String)
val structuredArg: StructuredFun = new {
  def buzz(bee: Int)(implicit ec: ExecutionContext) = Future.successful(s"$bee")
  val bee = 3
}

// ...and passed for execution along with the EC you like:
import scala.concurrent.ExecutionContext.Implicits.global
new Fun().foo(simpleArg)
new Fun().bar(structuredArg)
new Fun().byNameBaz(Future.failure(new RuntimeException))

This might be very handy if you want to wrap your async function argument with some logic around, e.g. transaction-like operations.


trait Foo {
  type MyFunction = (Int,Int) => Boolean

  def checkInts(f: MyFunction)
  def checkInts(f: Option[MyFunction])
}

Tags:

Function

Scala