7

As most of you probably know you can define functions in 2 ways in scala, there's the 'def' method and the lambda method...

making the 'def' kind generic is fairly straight forward

def someFunc[T](a: T) { // insert body here

what I'm having trouble with here is how to make the following generic:

val someFunc = (a: Int) => // insert body here

of course right now a is an integer, but what would I need to do to make it generic?

val someFunc[T] = (a: T) => doesn't work, neither does val someFunc = [T](a: T) =>

Is it even possible to make them generic, or should I just stick to the 'def' variant?

Electric Coffee
  • 11,733
  • 9
  • 70
  • 131
  • 4
    There are several ways to define functions in Scala, but using `def` is not one of them! The `def` keyword is used to define *methods*, which are in some sense an artifact of the JVM. Given suitable type information, Scala can automatically lift a method to a corresponding function, making it transparent and entirely frictionless, but nonetheless the two are different things. See http://stackoverflow.com/questions/17203510/partially-applied-functions-with-all-arguments-missing-in-scala/17203833#17203833 – Randall Schulz Jun 28 '13 at 21:09
  • 1
    google something that has to do with functions and scala, and I guarantee you that most of the results will show methods and people referring to methods as functions, hence the confusion – Electric Coffee Jun 28 '13 at 22:38
  • As understandable or explainable as the confusion is, it does not serve the practitioner to blur the distinction. – Randall Schulz Jun 29 '13 at 03:12

4 Answers4

8

As Randall Schulz said, def does not create a function, but a method. However, it can return a function and this way you can create generic functions like the identity function in Predef. This would look like this:

def myId[A] = (a: A) => a

List(1,2,3) map myId
// List(1,2,3)

List("foo") map myId
// List("foo")

But be aware, that calling myId without any type information infers Nothing. In the above case it works, because the type inference uses the signature of map, which is map[B](f: A => B) , where A is the type of the list and B gets infered to the same as A, because that is the signature of myId.

drexin
  • 24,225
  • 4
  • 67
  • 81
  • I actually wrote this as a solution before, but I got comments about it then becoming functions that returned functions, and thus not what I was looking for, I then deleted it... But it seems I wasn't the only one who came up with making a method (something a LOT of people call functions in scala) that then returns a function – Electric Coffee Jun 28 '13 at 22:36
  • If methods are side-effect free, they are essentially equivalent to functions. In other languages like haskell, every function with parameters returns functions as well, because every function in haskell is curried. Actually the myId method is as well a curried function and the same as if you would create the whole thing as a method and then partially apply it with 0 given parameters. – drexin Jun 28 '13 at 22:42
  • I'm very well aware of the concept of currying; this question arose from me trying to make a function with this type signature: `(a -> b) -> (a, c) -> (b, c)` but for the sake of simplicity I kept it down to a single generic type rather than three. The type signature I showed, as you know demonstrates a function that takes 2 parameters and returns a tuple, and depending on how many of the parameters are used, the function either returns the tuple or a function that takes a tuple and returns a tuple... So yes I'm familiar with the idea :) – Electric Coffee Jun 28 '13 at 22:47
  • I think this answer boils down to "stick to the def". – som-snytt Jun 28 '13 at 23:07
3

I don't believe it's possible. You can look at this previous post for more details:

How can I define an anonymous generic Scala function?

The only way around it (as one of the answers mentions) is to extend something like FunctionX and use a generic at the class level and then use that in the override of the apply function.

Community
  • 1
  • 1
cmbaxter
  • 35,283
  • 4
  • 86
  • 95
2

I don't believe it's possible either, but I'm a pessimist.

http://www.chuusai.com/2012/04/27/shapeless-polymorphic-function-values-1/

Edit:

Tell me if this isn't what you're asking, but this is why the accepted answer isn't what I thought you were asking for, see the link:

scala> :pa
// Entering paste mode (ctrl-D to finish)

def myId[A] = (a: A) => a

List(1,2,3) map myId
// List(1,2,3)

List("foo") map myId
// List("foo")

// Exiting paste mode, now interpreting.

myId: [A]=> A => A
res0: List[String] = List(foo)

scala> val f1 = myId[Int]
f1: Int => Int = <function1>

scala> val f2 = myId[String]
f2: String => String = <function1>

scala> List(1,2,3) map f2
<console>:10: error: type mismatch;
 found   : String => String
 required: Int => ?
              List(1,2,3) map f2
                              ^

scala> List("foo") map f1
<console>:10: error: type mismatch;
 found   : Int => Int
 required: String => ?
              List("foo") map f1
                              ^

The function values are not polymorphic, i.e., generic.

som-snytt
  • 39,429
  • 2
  • 47
  • 129
1

The closest thing is polymorphic functions I believe:

https://github.com/milessabin/shapeless#polymorphic-function-values

Channing Walton
  • 3,977
  • 1
  • 30
  • 59