Given a hex String, how can I programmatically create a Unicode String?
Example:
def f(x: String): String = s"\u$s"
fails to compile:
scala> def f(x: String): String = s"\u$s"
<console>:1: error: error in unicode escape
def f(x: String): String = s"\u$s"
^
I tried the following, but it failed:
scala> def f(x: String): String = "\\u" + x
f: (x: String)String
scala> f("0021")
res19: String = \u0021
scala> "\u0021"
res20: String = !
scala> res19 == res20
res21: Boolean = false
I don't know whether there's a way to call into the exact code the compiler is using, but doing it yourself seems simple enough.
Split the string into groups of 4 and use Integer.parseInt to get a code point, then convert it to a character.
scala> "27640021".grouped(4).map(Integer.parseInt(_, 16).toChar).mkString
res1: String = ❤!
When in doubt defer to the Java libs:
scala> def hexStrToChar(hex: String): Char = Integer.parseInt(hex, 16).toChar
hexStrToChar: (hex: String)Char
scala> hexStrToChar("0021")
res1: Char = !
Related
Python 3 will allow iterable unpacking such as:
>>> def foo(a, b, c): return a + b + c
...
>>> s1 = "one"
>>> s2 = ("two", "three")
>>> foo(s1, *s2)
'onetwothree'
I have seen How to apply a function to a tuple? and scala tuple unpacking but am having trouble emulating this in Scala (2.13):
scala> def foo(a: String, b: String, c: String): String = a + b + c
foo: (a: String, b: String, c: String)String
scala> val s1 = "one"
s1: String = one
scala> val s2 = Seq("two", "three")
s2: Seq[String] = List(two, three)
How can I mimic foo(s1, s2: _*)?
The closest I've gotten is with this combination of uncurried/curried, but frankly I'm not really understanding why this last attempt doesn't work:
scala> Function.uncurried((foo _).curried(s1))
res17: (String, String) => String = scala.Function$$$Lambda$897/0x0000000801070840#145f1f97
scala> Function.uncurried((foo _).curried(s1))(s2(0), s2(1))
res19: String = onetwothree
scala> Function.uncurried((foo _).curried(s1))(s2: _*)
^
error: not enough arguments for method apply: (v1: String, v2: String)String in trait Function2.
Unspecified value parameter v2.
If s2 were a tuple then things would be pretty straight forward.
def foo(a:String, b:String, c:String) :String = a + b + c
val s1 = "one"
val s2 = ("two", "three")
(foo(s1, _, _)).tupled(s2) //res0: String = onetwothree
But as a Seq() I think the best you can do is a wrapper that unpacks the elements for you.
def foox(ss:String*) :String = foo(ss(0), ss(1), ss(2)) //danger
val s3 = Seq("two", "three")
foox(s1 +: s3 :_*) //res1: String = onetwothree
There's no easy way (that I know of) to transition a non-varargs method to a varargs method/function.
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
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
The simpleName of String is literally "String":
scala> "abc".getClass.getSimpleName
res0: String = String
That makes sense, the simpleName of the type is the same name that I use to make one up in the first place, but consider Float:
scala> 32.2f
res4: Float = 32.2
scala> 23.2f.getClass.getSimpleName
res3: String = float
I was expecting 'Float' but I got '[f]loat' - why is the SimpleName behavior inconsistent with the representation of the object in the REPL?
Bonus points - is there a way that I can recover the exact name of the type I originally used, without any cumbersome mappings? What method is the REPL calling on the object to get it's correct name (with the capitol F).
The Scala type:
scala> import reflect.runtime._, universe._
import reflect.runtime._
import universe._
scala> def f[A](a: A)(implicit t: TypeTag[A]) = t
f: [A](a: A)(implicit t: reflect.runtime.universe.TypeTag[A])reflect.runtime.universe.TypeTag[A]
scala> f(2.0) // typeTag[Double]
res1: reflect.runtime.universe.TypeTag[Double] = TypeTag[Double]
scala> res1.tpe
res2: reflect.runtime.universe.Type = Double
scala> res2.typeSymbol.name
res3: reflect.runtime.universe.Symbol#NameType = Double
The boxed distinction is strictly an artifact of the underlying platform.
scala> java.lang.Float.TYPE
res4: Class[Float] = float
scala> classOf[java.lang.Float]
res5: Class[Float] = class java.lang.Float
What method is the REPL calling on the object to get it's correct name (with the capitol F).
It isn't calling any method on the object; if it did, it couldn't show two different types for the same object:
scala> val x = ""
res1: String = ""
scala> val y: Object = x
res2: Object = x
It's using compiler's information about types which can be accessed using TypeTags as som-snytt's answer shows.
Suppose I need to convert a String to Int in Scala. If the string is not a number I would like to return None rather than throw an exception.
I found the following solution
def toMaybeInt(s:String) = {
import scala.util.control.Exception._
catching(classOf[NumberFormatException]) opt s.toInt
}
Does it make sense ? Would you change/improve it ?
I'd use scala.util.Try which returns Success or Failure for a computation that may throw an exception.
scala> val zero = "0"
zero: String = 0
scala> val foo = "foo"
foo: String = foo
scala> scala.util.Try(zero.toInt)
res5: scala.util.Try[Int] = Success(0)
scala> scala.util.Try(foo.toInt)
res6: scala.util.Try[Int] = Failure(java.lang.NumberFormatException: For input string: "foo")
So, toMaybeInt(s: String) becomes:
def toMaybeInt(s:String) = {
scala.util.Try(s.toInt)
}
For getting an option in any case, regardless of possible exceptions due to number malformation,
import scala.util.Try
def toOptInt(s:String) = Try(s.toInt) toOption
Then
scala> toOptInt("123")
res2: Option[Int] = Some(123)
scala> toOptInt("1a23")
res3: Option[Int] = None
Further, consider
implicit class convertToOptInt(val s: String) extends AnyVal {
def toOptInt() = Try(s.toInt) toOption
}
Hence
scala> "123".toOptInt
res5: Option[Int] = Some(123)
scala> "1a23".toOptInt
res6: Option[Int] = None