Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

function

scala

I'm hoping there is a way to define a type for a function in Scala.

For example, say I want a function that takes two Ints and returns a Boolean, I could define a function that uses that like this:

def checkInts(f: (Int,Int) => Boolean) = {   // do stuff } 

Is there a way to define the type of f? Then I could do something like:

def checkInts(f: MyFunctionType) 

or

def checkInts(f: Option[MyFunctionType]) 
like image 277
Alex Black Avatar asked Dec 05 '09 23:12

Alex Black


2 Answers

trait Foo {   type MyFunction = (Int,Int) => Boolean    def checkInts(f: MyFunction)   def checkInts(f: Option[MyFunction]) } 
like image 62
Mitch Blevins Avatar answered Sep 21 '22 19:09

Mitch Blevins


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.

like image 39
Vladimir Salin Avatar answered Sep 19 '22 19:09

Vladimir Salin