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
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With