How is this a "type mismatch"? - scala

found : (Int, String, Option[java.lang.String])
required: (Int, String, Option[java.lang.String])
Pertinent code:
object M extends Table[(Int, String, Option[String])]("table") {
def msaid = column[Int]("msaid", O NotNull)
def name = column[String]("name", O DBType "varchar(255)")
def shape = column[Option[String]]("shape")
def * = msaid ~ name ~ shape
type T = (Int, String, Option[java.lang.String])
def apply(msa: T) = 1
def q() = db withSession { s: Session => (for (r <- M) yield M(*)).list()(s) }
^
^
...
I've also tried
type T = (Int, String, Option[String])
The ultimate goal is that I want all the selected columns to converted into an Object with named accessors, instead of being a tuple.
Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_07).
UPDATE:
Here's a Gist of the issue (slightly simplified from the above code and eliminates any String/java.lang.String "confusion" by using only Int.)

The error message didn't use to tell you which was the TupleN, though I think that was improved at some point. The mismatch is between a tuple and n args. Or not.
The fix is in 2.9.2. I notice your .sbt uses 2.9.1 scalaquery, in case that matters. And isn't scala-tools.org obsolete? Sorry for half-helping.
Speaking as a non-user, it looks like a Projection2 is not the Tuple you seek, albeit a Product:
class Projection2 [T1, T2] extends (Column[T1], Column[T2]) with Projection[(T1, T2)]
REPLing:
scala> M.column[Int]("id") ~ M.column[Int]("n")
res1: (Int, Int) = Projection2
scala> M(res1)
<console>:23: error: type mismatch;
found : (Int, Int)
required: (Int, Int)
M(res1)
^
scala> M.apply
def apply(v: (Int, Int)): Int
scala> M.apply((1,2))
res3: Int = 1

Related

Tuple with Int member not recognized where Long is required

I've got a function that expects a Tuple2, where one item must be a long. When I attempt to pass pairs with literal numbers using the -> implicit, they are being interpreted as Int instead of Long.
Here, the problem is demonstrated:
scala> val x: (Long, String) = (5, "test")
x: (Long, String) = (5,test)
scala> val x: (Long, String) = 5L -> "test"
x: (Long, String) = (5,test)
scala> val x: (Long, String) = 5 -> "test"
<console>:43: error: type mismatch;
found : (Int, String)
required: (Long, String)
val x: (Long, String) = 5 -> "test"
I suppose the problem is that when the implicit is applied, type inference locks in on Int, but in the first example, type inference is nice enough to consider the number a Long.
But my DSL works much better if I can use -> and omit the L suffix. Is there a way to achieve this?
Unfortunately, Int is not formally a subtype of Long. Thus, an (Int, String) can not be passed where a (Long, String) is expected, despite the fact that Tuple2 is covariant in its type parameters.
However, Int is viewable as Long. So, you can design a function that will upconvert an Int to a Long the following way:
scala> def goodFunc[LongLike <% Long](arg: (LongLike, String)) = { "whatevs" }
goodFunc: [LongLike](arg: (LongLike, String))(implicit evidence$1: LongLike => Long)String
scala> goodFunc(5 -> "test")
res4: String = whatevs
Or, better yet, use:
def goodFunc[LongLike](arg: (LongLike, String))(implicit ev: LongLike => Long) = { "whatevs" }
, since <% is deprecated.

How to find instance of a value type in Scala?

I know isInstanceOf can be used to find value type, but how do I find the type of 'str'?
What type is it?
scala> val str = ("Scala", "Elixir","Spark")
str: (String, String, String) = (Scala, Elixir, Spark)
The following throws an error (exclude Any/AnyRef etc for now):
scala> str.isInstanceOf[List]
<console>:13: error: type List takes type parameters
str.isInstanceOf[List]
scala> str.isInstanceOf[String]
<console>:13: warning: fruitless type test: a value of type (String, String, String) cannot also be a String (the underlying of String)
str.isInstanceOf[String]
^
res9: Boolean = false
I can check it this way but is there a name for this?
scala> str.isInstanceOf[(String, String, String)]
res12: Boolean = true
Use :type in scala repl to find type
Actual type is Tuple3[String, String, String]
str.isInstanceOf[Tuple3[String, String, String]]
Scala REPL
scala> val str = ("Scala", "Elixir","Spark")
str: (String, String, String) = (Scala,Elixir,Spark)
scala> :type str
(String, String, String)
scala> str.isInstanceOf[Tuple3[String, String, String]]
res2: Boolean = true
scala> str.getClass
res3: Class[_ <: (String, String, String)] = class scala.Tuple3
How to determine val type programmatically?
For instance, you want to know the type of the value is some specific type?
// assign x value
val x: Any = "this is string"
// custom function evaluate type
def f[T](v: T) = v match {
case _: Int => println("Int")
case _: String => println("String")
case _ => println("Unknown")
}
// determine val type
f(x)
Yet another way to determine a type programmatically is using Manifest:
scala> def getType[T: Manifest](t: T): Manifest[T] = manifest[T]
getType: [T](t: T)(implicit evidence$1: Manifest[T])Manifest[T]
scala> val str = ("Scala", "Elixir","Spark")
str: (String, String, String) = (Scala,Elixir,Spark)
scala> getType(str)
res0: Manifest[(String, String, String)] = scala.Tuple3[java.lang.String, java.lang.String, java.lang.String]
The modern (meaning Scala 2.10 or later), Scala way of programmatically getting the compile time type of something is using a TypeTag.
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> def getType[T: TypeTag](value: T) = typeOf[T]
getType: [T](value: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.Type
scala> val str = ("Scala", "Elixir","Spark")
str: (String, String, String) = (Scala,Elixir,Spark)
scala> println(getType(str))
(java.lang.String, java.lang.String, java.lang.String)
scala> getType(str) <:< typeOf[(String,String,String)]
res1: Boolean = true
scala> getType((1,2,3)) <:< typeOf[(String,String,String)]
res2: Boolean = false
getClass will give your the erased runtime class. isInstanceOf[T] will test whether the erased runtime class is the same as or a subclass of the erased runtime class of T.
And "erased" means that the following evaluates to true.
(1,2,3).isInstanceOf[(String,String,String)]
"runtime" and "compile time" mean that this is true:
val a: Any = (1,2,3)
a.isInstanceOf[(_,_,_)]
while this is false:
val a: Any = (1,2,3)
getType(a) <:< typeOf[(Int,Int,Int)]
This method can help you get the type of any val/var at runtime, it's also works in compiled code.
import scala.reflect.runtime.universe._
def printType[T](x: T)(implicit tag: TypeTag[T]): Unit = println(tag.tpe.toString)
printType(List[Int](1,2,3)) // output: List[Int]
printType(("xxx", 123, 0.1)) // output: (String, Int, Double)
printType(2) // output: Int

Is it possible to force named parameters in scala?

In some method I would like to force parameters to be named. The reason being autogenerated code for which the order of parameters is unspecified (and will remain that way).
The closest I can get is
private val _forceNamed: Object = new Object()
def doSomething(forceNamed: Object = _forceNamed, arg1: String, arg2: String, ...): Unit = {
if (forceNamed != _forceNamed) {
throw Exception(something)
}
// actually do stuff
}
However this only fails at runtime, whereas something failing at compile time would be much nicer.
If you want to close the loophole of being able to pass in null, you can use a value class as a guard.
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Foo {
import Foo._
def foo(x: Bar = bar, a: String, b: String) = println(a + b)
}
object Foo {
private[Foo] class Bar(val i: Int) extends AnyVal
private val bar = new Bar(42)
}
// Exiting paste mode, now interpreting.
defined class Foo
defined object Foo
scala> val f = new Foo
f: Foo = Foo#4a4f9c58
scala> f.foo(null, "", "")
<console>:13: error: type mismatch;
found : Null(null)
required: Foo.Bar
f.foo(null, "", "")
^
We have this in our code base for this purpose:
object `(Please use explicitly named arguments)`
def foo(
`(Please use explicitly named arguments)`:
`(Please use explicitly named arguments)`.type =
`(Please use explicitly named arguments)`,
namedArg1: Int,
namedArg2: String,
...
) = ...
Something like this maybe:
class Foo {
class Bar private[Foo]()
private val bar = new Bar
def foo(x: Bar= bar, a: String, b: String) = println(a + b)
}
What a great idea.
It looks like hygiene issues with default args prohibit singleton types.
$ scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.
scala> private val x = new Object ; def f(foo: x.type = x, i: Int) = i
<console>:11: error: private value x escapes its defining scope as part of type x.type
private val x = new Object ; def f(foo: x.type = x, i: Int) = i
^
scala> val x = new Object ; def f(foo: x.type = (x: x.type), i: Int) = i
x: Object = java.lang.Object#1e54cb33
f: (foo: x.type, i: Int)Int
scala> f(i = 42)
<console>:13: error: type mismatch;
found : Object
required: x.type
f(i = 42)
^
or no, this looks OK:
private[this] val x: Object = new java.lang.Object();
<stable> <accessor> def x: Object = $iw.this.x;
def f(foo: x.type = $iw.this.x, i: Int): Int = i;
<synthetic> def f$default$1: x.type = $iw.this.x
or is the problem the assignment to the default value?
but you can't do this:
scala> val x: x.type = new Object
<console>:36: error: recursive value x needs type
val x: x.type = new Object
^
I guess this works because you don't have to tell it that x is x.type:
scala> object x
defined object x
scala> def f(y: x.type = x, i: Int) = i
f: (y: x.type, i: Int)Int
scala> f(i = 42)
res2: Int = 42
That still allows explicitly providing x, which could be obfuscated.
I'm too scared to investigate why this fails:
scala> object x$$ ; def f(y: x$$.type = x$$, i: Int) = i
defined object x$$
f: (y: .type, i: Int)Int
scala> f(i = 42)
res0: Int = 42
scala> f(x$$, 42) // or x$$$
<console>:13: error: not found: value x$$
f(x$$, 42)
^
But that suggests that even though the object is public, access to it is somehow crippled by name mangling.
Welcome to Scala 2.12.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).
Type in expressions for evaluation. Or try :help.
scala> type `(Please use explicitly named arguments)` = Nothing
defined type alias $u0028Please$u0020use$u0020explicitly$u0020named$u0020arguments$u0029
scala> def foo(`(Please use explicitly named arguments)`: => `(Please use explicitly named arguments)` = ???, i: Int, j: Int) = i + j
foo: ((Please use explicitly named arguments): => (Please use explicitly named arguments), i: Int, j: Int)Int
scala> foo(null, 1, 4)
<console>:13: error: type mismatch;
found : Null(null)
required: (Please use explicitly named arguments)
(which expands to) Nothing
foo(null, 1, 4)
^
scala> foo(i = 1, j = 4)
res1: Int = 5

How to use ConcurrentHashMap computeIfAbsent() in Scala

I'm using a ConcurrentHashMap in Scala and I would like to use the computeIfAbsent() method but can't figure out the syntax for the second argument. Can someone show me what would be the proper syntax?
When running the following code
val data = new ConcurrentHashMap[String, LongAdder]
data.computeIfAbsent("bob", k: String => new LongAdder()).increment()
I'm getting the following error
Type mismatch, expected: Function[_ >: String, _ <: LongAdder], actual: (String) => Any
Thanking you in advance
Francis
The problem is that you're using java.util.concurrent.ConcurrentHashMap, which accepts java.util.function.Function as a parameter for computeIfAbsent() instead of scala.Function1 which you pass to it.
Since scala doesn't support lambda conversion for functional interfaces as Java does (at least not without the -Xexperimental flag), you can solve this by implementing a java.util.function.Function explicitly:
val data = new ConcurrentHashMap[String, LongAdder]
val adderSupplier = new java.util.function.Function[String, LongAdder]() {
override def apply(t: String): LongAdder = new LongAdder()
}
data.computeIfAbsent("bob", adderSupplier).increment()
Alternatively, if you need this more often, you may write a utility conversion function or even an implicit conversion:
object FunctionConverter {
implicit def scalaFunctionToJava[From, To](function: (From) => To): java.util.function.Function[From, To] = {
new java.util.function.Function[From, To] {
override def apply(input: From): To = function(input)
}
}
}
import FunctionConverter._
val data = new ConcurrentHashMap[String, LongAdder]()
data.computeIfAbsent("bob", (k: String) => new LongAdder()) // <- implicit conversion applied here
If you enable -Xexperimental flag you can use scala anonymous function notation for this:
scala> val data = new java.util.concurrent.ConcurrentHashMap[String, Int]
data: java.util.concurrent.ConcurrentHashMap[String,Int] = {}
scala> data.computeIfAbsent("bob", _.size)
res0: Int = 3
Note that you still can't pass regular scala Function
scala> val f: String => Int = _.size
f: String => Int = <function1>
scala> data.computeIfAbsent("bob", f)
<console>:13: error: type mismatch;
found : String => Int
required: java.util.function.Function[_ >: String, _ <: Int]
data.computeIfAbsent("bob", f)
^
But eta-expansion will work
scala> def a(s: String): Int = s.size
a: (s: String)Int
scala> data.computeIfAbsent("bob", a)
res3: Int = 3

How to get Scala function's parameters / return type?

I have a function, and would like to obtain its parameter types and return type for use in Scala macros.
scala> val fn = (a: String, b: Double) => 123
fn: (String, Double) => Int = <function2>
scala> fn.getClass
res1: Class[_ <: (String, Double) => Int] = class $anonfun$1
In the above example, the parameter types and return type already get printed at both lines, but I don't know how to access them. Even with toString I'd be stuck with the <function2> and class $anonfun$1 parts right of the = sign -- otherwise a bit of ugly string parsing might have done.
I found that the MethodSymbolApi offers a way to extract this information for methods, but it seems like this might not help for this particular case.
I'm currently looking into AST parsing (as part of scala.meta) to extract the information, but I'd think this question would seem basic enough to be covered by the standard reflection library, though I've failed to find what I want in there. Any ideas?
Edit based on #johanandren's answer:
I haven't found a neater way to extract them from the TypeTag/Type yet, but this does already work. :)
scala> val fn = (a: String, b: Double) => 123
scala> import scala.reflect.runtime.{universe => ru}
scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
scala> getTypeTag(fn).tpe.toString.split(" => ")
res179: Array[String] = Array((String, Double), Int)
getClass is part of the Java reflection API which does not quite understand Scala types, you should look at the Scala Reflection API instead. This should get you started, http://docs.scala-lang.org/overviews/reflection/overview.html
Not sure but I think a TypeTag for the function type is what you want.
Just for completness, when you are in Scala REPL, you can access the type as:
scala> val fn = (a: String, b: Double) => 123
fn: (String, Double) => Int = <function2>
scala> :type fn
(String, Double) => Int
At runtime, Scala compiler won't have complete type information. So it forms a code snippet fn, ( also does its own symbol table lookups ).
https://github.com/scala/scala/blob/v2.10.5/src/compiler/scala/tools/nsc/interpreter/ILoop.scala#L449
Then passes it to the compiler which then attaches the type information to an implicit evidence type.
( explained here I want to get the type of a variable at runtime )
scala> import scala.reflect.runtime.universe.{TypeTag, typeTag}
import scala.reflect.runtime.universe.{TypeTag, typeTag}
scala> def getTypeTag[T: TypeTag](obj: T) = typeTag[T]
getTypeTag: [T](obj: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]
Now we have an evidence that will give us the exact type information:
scala> getTypeTag(fn)
res0: reflect.runtime.universe.TypeTag[(String, Double) => Int] = TypeTag[(String, Double) => Int]
scala> val targs = res0.tpe.typeArgs
targs: List[reflect.runtime.universe.Type] = List(String, Double, Int)
Now we can access the types with ease:
scala> val (in, out) = (ta.init, ta.last)
in: List[reflect.runtime.universe.Type] = List(String, Double)
out: reflect.runtime.universe.Type = Int
scala> println(s"INPUTS: $in")
INPUTS: List(String, Double)
scala> println(s"OUTPUT: $out")
OUTPUT: Int