3 votes

Quel est le supertype de toutes les fonctions en Scala ?

Je sais que je peux faire instanceOf les contrôles contre Function1 o Function2 etc mais existe-t-il un moyen générique de voir si quelque chose est une fonction ou non (il peut y avoir un nombre arbitraire d'args). J'ai essayé de définir quelque chose comme ceci :

type FuncType = (Any*) -> Any

Mais cela n'a pas fonctionné non plus. En fait, j'ai un code qui ressemble à ceci :

call = (name: Any, args: Any*) -> if name.isFunction then name.castAs[Function].apply(args) else name
aFunction = (name: String) => "Hello " + name
notAFunction = "Hello rick"
call(aFunction, "rick")
call(notAFunction)

4voto

DaoWen Points 14480

Il n'existe pas de supertype général pour tous les types de fonctions.

Scala n'a aucun moyen d'abstraire l'arité d'une fonction. Cependant, vous pouvez vous pencher sur le Sans forme qui introduit un élément appelé HList que vous pouvez utiliser pour abstraire l'arité des fonctions.

Cependant, je pense que ce n'est pas vraiment ce dont vous avez besoin. On dirait que tu veux juste faire une vérification du genre "est-ce une fonction ?". Vous pouvez penser que c'est bizarre qu'il n'y ait pas d'agnostic d'arité. Function mais il est pratiquement toujours nécessaire de connaître l'arité d'une fonction si l'on veut en faire quelque chose d'utile.

Alternativement, vous pourriez faire quelque chose avec la fonction curried sur la fonction, qui renverra un Function1 .

3voto

wingedsubmariner Points 7382

Non, il n'y a aucun moyen de le faire, sauf à passer en revue et à vérifier chacun des éléments suivants Function1 , Function2 etc. Le parent de chacun de ces traits est AnyRef ce qui ne vous aidera pas à les distinguer des autres. Le site apply pour chacun de ces traits prend un nombre différent de paramètres, il n'y a donc aucun moyen de leur donner un parent qui a une méthode apply. La méthode la plus proche de ce que vous essayez de faire est probablement la suivante :

def arbitraryFunction(function: AnyRef, args: Seq[Any]): Any = {
  function match {
    case f: Function1[Any, Any] => f(args(0))
    case f: Function2[Any, Any, Any] => f(args(0), args(1))
    // and so on
  }
}

Mais c'est insensé et dangereux, et cela entraînera des exceptions au moment de l'exécution si les types sont incorrects, par exemple

arbitraryFunction((x: Int) => x * 2, List("I'm a String!"))

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