41 votes

Comment définir un type pour une fonction en Scala ?

J'espère qu'il existe un moyen de définir un type pour une fonction en Scala.

Par exemple, si je veux une fonction qui prend deux Ints et renvoie un booléen, je peux définir une fonction qui l'utilise comme ceci :

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

Existe-t-il un moyen de définir le type de f ? Je pourrais alors faire quelque chose comme :

def checkInts(f: MyFunctionType)

ou

def checkInts(f: Option[MyFunctionType])

49voto

Mitch Blevins Points 7646
trait Foo {
  type MyFunction = (Int,Int) => Boolean

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

1voto

Vladimir Salin Points 903

Pour compléter la réponse originale :

Pour certains cas plus complexes, vous pouvez opter pour des types structurels qui peuvent également inclure des définitions de fonctions. [1] , [2] .

Pour ce qui est des exemples particuliers et de l'utilisation pratique, les types de fonctions peuvent être utilisés de manière très intéressante avec les éléments suivants Future par exemple pour passer un ExecutionContext et exécute réellement une fonction asynchrone après l'avoir passée.

Notez cependant que si vous avez toujours votre CE disponible dans la classe exécutante et que vous n'avez donc pas besoin de le passer, vous pouvez opter pour des arguments par nom ("donnez moi juste une Future résultat") [3] .

Un projet d'exemple ci-dessous montre cette idée simple : il a un type de fonction juste avec l'élément ec et un type structurel qui pourrait également prendre certains paramètres pour la fonction à exécuter. Il montre également une alternative avec la fonction by-name :

/** 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))

Cela peut s'avérer très pratique si vous voulez envelopper votre argument de fonction asynchrone avec une certaine logique autour, par exemple, d'opérations de type transaction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X