Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A compiling error about scala type inference

Tags:

types

scala

I am doing a simple exercise which asks me to implement a standalone 'map' function on a list using foldRight. And the solution I came up with is this:

def mapFun[T,U](xs: List[T], f: T => U): List[U] = {
  (xs foldRight List[U]())((x, y) => f(x) :: y)
}

val sl = List(1,2,3)

//now try to square every item
mapFun(sl, x => x * x)  //**missing parameter type**
mapFun(sl, (x:Int) => x * x) //ok, gives List(1,4,9)

As is denoted above an explicit 'Int' type must be specified for the code to compile. However it seems to me that the compiler should be able to infer the type of 'x' since 'sl' is of type 'List[Int]' which means T is 'Int' and then the 'x*x' expression's type U should also be 'Int'.

I guess it may have something to do with the variance or contra-variance kind of stuff or something where sub typing is mixed with generic typing..

My scala compiler version is 2.11 bundle (dynamics).


Supplement to the standard answer: From Functional Programming in Scala Chapter 3:

This is an unfortunate restriction of the Scala compiler; other functional languages like Haskell and OCaml provide complete inference, meaning type annotations are almost never required

like image 217
user1206899 Avatar asked Mar 10 '23 06:03

user1206899


1 Answers

Scala's type inference doesn't flow inside a parameter list, only between parameter lists. This will work:

def mapFun[T,U](xs: List[T])(f: T => U): List[U] = {
  (xs foldRight List[U]())((x, y) => f(x) :: y)
}

val sl = List(1,2,3)
println(mapFun(sl)(x => x * x))
like image 157
Yuval Itzchakov Avatar answered Mar 20 '23 12:03

Yuval Itzchakov