2

I am trying to understand the type parameters when applied to a function.

I would like to use Generic Types in the below method but using String and Int for my understanding.

When I define a function as below

  def myfunc[Int](f:String => Int):Int =  {
    Integer.min(1,2)
  }

it complains

 found   : scala.this.Int
 required: Int&0
      Integer.min(1,2)

However if I remove the return type of the function ( which I understand is not required), it compiles fine.

I am not able to infer why removing the return type makes the compilation successful.

Appreciate your help.

-Amit

developer_hatch
  • 15,898
  • 3
  • 42
  • 75
Amit
  • 1,111
  • 1
  • 8
  • 14

6 Answers6

5

Try

def myfunc(f:String => Int):Int =  {
  Integer.min(1,2)
}

When you write def myfunc[Int](f:String => Int):Int you declare type parameter Int, which hides standard type scala.Int. This is the same as if you declared def myfunc[A](f:String => A):A. When you remove return type it's inferred to be scala.Int, i.e. def myfunc[A](f:String => A) is def myfunc[A](f:String => A):Int

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
  • Yeah, it did work when I removed the return type and that is where I got confused and hence posted the question. Maybe this is what I am failing to understand - "you declare type parameter Int, which hides standard type scala.Int" – Amit Aug 29 '19 at 22:58
  • @Amit you hide it for your own use, but the compiler does know the fully qualified name of the type. For example, you may use `_root_scala.Int` as the return type, it should work. – Luis Miguel Mejía Suárez Aug 29 '19 at 23:16
2

If you want to use generics, first you have to understand that the name of the variable types starts capitalized and they are names, just that so [Int] in your function is the name of the type variable, an example:

object Main extends App{
    val f: String => Int = s => 4
    println(myfunc(f, "nothing useful"))

    def myfunc[A,B](f:A => B, x: A):B =  {
      f(x)
    }
}

here the names are A and B and the return type is of type B

developer_hatch
  • 15,898
  • 3
  • 42
  • 75
1

Question: What's the difference between these 3 methods?

def myfunc1[X](f:String => X):X =
  Integer.min(1,2)

def myfunc2[Int](f:String => Int):Int =
  Integer.min(1,2)

def myfunc3[IDontGetTypeParameters](f:String => IDontGetTypeParameters):IDontGetTypeParameters =
  Integer.min(1,2)

Answer: Nothing. From the compiler's point of view they are the same, and they fail to compile for the same reason: each is defined to return the type of the type parameter but tries to return an integer (Scala.Int) instead.

jwvh
  • 50,871
  • 7
  • 38
  • 64
0

A quick one liner:

def myfunc(f:String => Int):Int = Integer.min(1,2)
1218985
  • 7,531
  • 2
  • 25
  • 31
0

It's good trying to make your own examples, but have you tried any examples from books, articles or tutorials? There's probably a good one in Scala for the Impatient by Cay Horstmann.

Here's a decent example from the Tour de Scala:

def listOfDuplicates[A](x: A, length: Int): List[A] = {
  if (length < 1)
    Nil
  else
    x :: listOfDuplicates(x, length - 1)
}

Sometimes you can omit the type parameter, but let's ignore that for now and declare the types explicitly:

listOfDuplicates[Int](43, 5) // Should give a list with 43 five times
listOfDuplicates[String]("Hello, world! ", 3) // "Hello, world!" thrice
listOfDuplicates[(Int, Int)]((0, 1), 8) // The pair (0, 1) eight times

This shows that A can be Int, String, (Int, Int) or just about anything else we can think of. Not sure you'd ever have a practical need for this, but you can even do something like this:

def wrapLength(str: String): Int = str.length

listOfDuplicates[String => Int](wrapLength(_), 2)

Here's a Scastie snippet in which you can play around with this.

Alonso del Arte
  • 1,005
  • 1
  • 8
  • 19
0

Your generic type name shouldn't be one of the reserved words in Scala. Int itself is a reserved word for a type. In this cases, for simplicity and understanding, we use some basic characters like T or R as the generic type if you really keen to use generics for other functions.