Search code examples
scalafunctiontypesparameters

Define function with any kind of parameters and known return type


I am sure something like this should exist and that I just don't know how to phrase it.

So is there a way to define a generalized function which can take any number of parameters (from zero) of any type and return a value of known type? So if we define

f: <something_here> => Int

Any function that returns Int shall satisfy this than.


Solution

  • No, there is not, without losing type-safety (assuming I understand your question correctly). Ultimately, the only way to use a value of type e.g. String => Int is to supply a String to its apply method, but how would you know what type of arguments to supply to "Any function that returns Int"?

    If you are willing to lose type-safety (you shouldn't), you can achieve it with something like

    class UnsafeFunction[A] {
      def apply(xs: Any*): A
    }
    
    object UnsafeFunction {
      implicit def fromF1[A, B](f: A => B): UnsafeFunction[B] = new UnsafeFunction[B] { 
        def apply(xs: Any*) = f(xs(0).asInstanceOf[A])
      }
      implicit def fromF2[A, B, C](f: (A, B) => C): UnsafeFunction[C] = new UnsafeFunction[C] { 
        def apply(xs: Any*) = f(xs(0).asInstanceOf[A], xs(1).asInstanceOf[B])
      }
      ...
    }
    

    This allows assigning any function which returns Int to a value of type UnsafeFunction[Int], or passing it to a method which takes such arguments. Again, I very much don't suggest using this in practice.

    What you can usefully do is use generic types such as A => Int and (A, B) => Int, where A is a type parameter of your type or method. Scala itself doesn't allow you to unify functions with different number of parameters, but there is a library which does: Shapeless. Unfortunately, using it is far from trivial.