Why doesn't scala infer a type from typical type parameters?

Assume this function

def func[A](data: List[A], mapper: A => String) = { data.map(item => mapper(item)) } 

Why this code does not compile:

 val list = List(1, 2, 3) func(list, a => a.toString) 

But it does:

 val list = List(1, 2, 3) func[Int](list, a => a.toString) 

or

 val list = List(1, 2, 3) func(list, (a: Int) => a.toString) 

While type a can be inferred from List Int . Why does scala infer a type here?

Is there another way?

+8
scala type-inference
source share
1 answer

There is another way! This also happens for good syntactic sugar:

 def func[A](data: List[A])(mapper: A => String) = data map mapper 

which is as follows:

 func(myList){ case Left(one) => one case Right(_) => default } 

The reason you cannot get type information as you expect is type information in Scala from left to right. In other systems, type information is known and output for use where it is defined. Sometimes you have to get around these limitations, but at the same time in this case you can work with something similar to your own management structure.

So...

 func[Int]( //I've just told the typer what the information is and it can flow to the right. func(list //the typer has to deduce the type and without a guide can not figure out what a => a.toString should be 

This is also an old "problem" that you can see here SI-4773 .

Reply to Q in a comment :

If you want to have Seq[A => B] , I would do something similar to

 func[A, B](data: List[A])(actions: A => B*) = actions map { data map } 

which uses varargs (translates to WrappedArray , therefore map ) to accept any list of commands so you can go through,

 func(list)(_.name, _.age, _.sex, _.stalker) 

to pull and match what you went through:

 func[A, B](data: List[A])(actions: (String, A => B)*) = actions map { case (name, f) => (name, data map f) } 

in which you use the case to match the pattern and retrieve the tuple.

+10
source share

All Articles