Reputation: 13
Given following two Scala functions, both compiles as expected.
scala> def toList[A](a: A) = List(a)
toList: [A](a: A)List[A]
scala> def foo[A](f: A => List[A], b: A) = f(b)
foo: [A](f: A => List[A], b: A)List[A]
Yet, when you run it, it gave following error message:
scala> foo(toList, 12)
<console>:14: error: type mismatch;
found : Nothing => List[Nothing]
required: Int => List[Int]
foo(toList, 12)
Why does Scala think toList
function is of Nothing => List[Nothing]
instead of Int => List[Int]
?
Upvotes: 0
Views: 59
Reputation: 3863
The Scala compiler will try to infer the type parameters of the method, it will look to the parameters defined int he first parenthesis and try to extract the type from them, if it can not it will pick the next parameter group to infer the type, and so on...
The best way to define that function is like this
def foo[A](b: A)(f: A => List[A]) = f(b)
Giving the parameters in this order will allow you to avoid the need of giving some hint to the compliler. You can call this function like this:
foo(2.0d)(toList)
And you will get a List[Double]
If you keep the other order you will need to give a hint to the compiler in order to figure out the type parameter A
foo(toList[Double], 2.0d)
Upvotes: 1
Reputation: 41957
According how foo
is defined, foo(12, toList)
is wrong in passing the arguments. Correct way is foo(toList, 12)
Why does Scala think toList function is of Nothing => List[Nothing] instead of Int => List[Int]?
12
is of Int
type and since foo
is
def foo[A](f: A => List[A], b: A) = f(b)
its expecting A
type which is Int
for the toList
function as well.
If you call foo
as foo(toList, 12D)
we get following error
<console>:22: error: type mismatch;
found : Nothing => List[Nothing]
required: Double => List[Double]
foo(toList, 12D)
Its because 12D
is Double type
and toList
is expected to be of Double
too.
So the correct way would be
foo(toList[Any], 12)
Upvotes: 1