Skip to content

Instantly share code, notes, and snippets.

@ScrapCodes
Last active August 9, 2016 09:48
Show Gist options
  • Save ScrapCodes/10713689 to your computer and use it in GitHub Desktop.
Save ScrapCodes/10713689 to your computer and use it in GitHub Desktop.
Understanding type inference. Why do I have to specify the types explicitly ?
scala> import scala.reflect._
import scala.reflect._
scala> def f[K: ClassTag, V: ClassTag, T<:Product2[K, V]](names: T, values: T) = {
val x = values;
println(classTag[K]);
names.productIterator.toList.zip(x.productIterator.map(_.toString).toSeq).map(kv => kv._1+"="+kv._2)
}
| | | | f: [K, V, T <: Product2[K,V]](names: T, values: T)(implicit evidence$1: scala.reflect.ClassTag[K], implicit evidence$2: scala.reflect.ClassTag[V])List[String]
scala> f(("one", "two"), ("1", "2")) // Why can't these types be inferred ?
<console>:13: error: inferred type arguments [Nothing,Nothing,(String, String)] do not conform to method f's type parameter bounds [K,V,T <: Product2[K,V]]
f(("one", "two"), ("1", "2"))
^
<console>:13: error: type mismatch;
found : (String, String)
required: T
f(("one", "two"), ("1", "2"))
^
<console>:13: error: type mismatch;
found : (String, String)
required: T
f(("one", "two"), ("1", "2"))
^
scala> f[String, String](("one", "two"), ("1", "2"))
<console>:13: error: wrong number of type parameters for method f: [K, V, T <: Product2[K,V]](names: T, values: T)(implicit evidence$1: scala.reflect.ClassTag[K], implicit evidence$2: scala.reflect.ClassTag[V])List[String]
f[String, String](("one", "two"), ("1", "2"))
^
scala> f[String, String, (String, String)](("one", "two"), ("1", "2"))
java.lang.String
res16: List[String] = List(one=1, two=2)
scala> f[String, Int, (String, String)](("one", "two"), ("1", "2"))
<console>:13: error: type arguments [String,Int,(String, String)] do not conform to method f's type parameter bounds [K,V,T <: Product2[K,V]]
f[String, Int, (String, String)](("one", "two"), ("1", "2"))
^
scala>
@Sciss
Copy link

Sciss commented Apr 26, 2014

I have run into almost the same thing just yesterday: http://stackoverflow.com/questions/23275767/fixing-type-inference-for-higher-kinded-type

Apparently, your other type parameters K and V must be visible inside the argument list. Don't ask me why, but then you can make it work:

def g[K: ClassTag, V: ClassTag, T <: Product2[K, V]](names: T with Product2[K, V], 
  values: T with Product2[K, V]) = "ok"

g(("one", "two"), ("1", "2"))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment