Accept anonymous comparator in Scala? - java

How can I accept a function to pass to Vector.sortBy() in scala as an argument?
Currently I have a function like this:
private def buildTree(data: Vector[Data2D]): Node = {
var sorted: Vector[Data2D] = data.sortBy(_.x)
// etc...
}
However, I would like to pass either "_.x" (sort on x) or "_.y" as an argument to the function, so I can do something like this:
private def buildTree(data: Vector[Data2D], comparator): Node = {
var sorted: Vector[Data2D] = data.sortBy(comparator)
// etc...
if(comparator == _.x){
buildTree(data, _.y)
}
}
So I would like to check what the current "comparator" is, and then recurse passing it the comparator for the y coordinate.
I hope this is clear. In Java I would write it as:
private Node buildTree(List<Data2D> data, Comparator<Data2D> comparator) {
// Sorted on x or y
Collections.sort(data, comparator);
// ... snip ...
if (comparator instanceof XComparator) {
// Recurse
Node subtree = buildTree(data, YComparator.INSTANCE);
ret.setSubtree(subtree);
}
return ret;
}
// Then build tree is called like:
Node root = tree.buildTree(data, XComparator.INSTANCE)

Actually, you want an Ordering. Like this:
class XOrdering extends Ordering[Data2D] {
override def compare(x: Data2D, y: Data2D): Int = Ordering.Int(x.x, y.x)
}
class YOrdering extends Ordering[Data2D] {
override def comapre(x: Data2D, y: Data2D): Int = Ordering.Int(x.y, y.y)
}
private def buildTree(data: Vector[Data2D], ordering: Ordering[Data2D]): Node = {
var sorted: Vector[Data2D] = data.sorted(ordering)
// etc...
ordering match {
case _: XOrdering => buildTree(data, YOrdering)
case _: YOrdering => buildTree(data, XOrdering)
case _ => error("I don't know what that ordering is!")
}
}
The sortBy method just creates an Ordering for you. sortBy(_.x) is equivalent to sorted(Ordering.by(_.x)).

If you check the docs, you see that sortBy takes one argument: f: A => B. Looks like a generic function that takes A as an argument and produces a B. So, let's give that a try:
val orderX = (d: Data2D) => d.x
val orderY = (d: Data2D) => d.y
which defines the two functions that we want. Now we can call
data.sortBy(orderer)
and test
if (orderer==orderX) buildTree(data, orderY)
(though I would recommend passing in both comparators as arguments rather than searching for specific constants).

Related

Scala: Reflection APIs to call one of the two methods with the same name

I am trying to use Scala Reflection APIs to call one of the two methods with the same name. Only difference is that one of them takes an argument but the other one doesn't. I want to call the one that doesn't take any arguments. I am trying something like this:
val ru = scala.reflect.runtime.universe
val rm = ru.runtimeMirror(getClass.getClassLoader)
val instanceMirror = rm.reflect(myInstance)
val methodSymbol = instanceMirror.symbol.typeSignature.member(ru.TermName("getXyzMethod")).asTerm.alternatives
if (methodSymbol != null && methodSymbol.nonEmpty) {
try {
val method = instanceMirror.reflectMethod(methodSymbol.head.asMethod)
val value = method()
}
} catch {
case e: java.lang.IndexOutOfBoundsException =>
val method = instanceMirror.reflectMethod(methodSymbol.last.asMethod)
val value = method()
case e: Exception =>
}
}
This works but as you can see this is a bit ugly. The reason for doing it this way is that the 'methodSymbol' is a list in which the method I want is sometimes in the 'head' position & sometimes in the 'last' position.
How do I use Scala Reflection APIs to get only the method that I want which has no arguments?
You can do something like this:
val ru: JavaUniverse = scala.reflect.runtime.universe
val rm: ru.Mirror = ru.runtimeMirror(getClass.getClassLoader)
val instanceMirror: ru.InstanceMirror = rm.reflect(myInstance)
val methodSymbol: Seq[ru.Symbol] =
instanceMirror.symbol.typeSignature.member(ru.TermName("getXyzMethod")).asTerm.alternatives
val maybeMethods: Try[ru.MethodSymbol] = Try(methodSymbol.map(_.asMethod).filter(_.paramLists.flatten.isEmpty).head)
val result: ru.MethodMirror = maybeMethods match {
case Failure(exception) => //do something with it
throw new Exception(exception)
case Success(value) => instanceMirror.reflectMethod(value)
}
println(result)
This will always return the method with no parameters.
Being like this:
def getXyzMethod() = ???
or
def getXyzMethod = ???
Adjust the size of the sequence if that method as more parameters, so if the method you want has exactly 1 parameter:
val maybeMethods: Try[ru.MethodSymbol] = Try(methodSymbol.map(_.asMethod).filter(_.paramLists.flatten.size==1).head)
And so on, hope this helps.

Scala accept only String or Int generic case class in List

I have a case class defined as below
case class ChooseBoxData[T](index:T, text:String)
Is it possible to declare a List so that the list only accept type of ChooseBoxData[String] and ChooseBoxData[Int]?
What I expected is something like:
val specialList:List[some type declaration] = List(
ChooseBoxData[String]("some string","some string"),/* allow, because is ChooseBoxData[String]*/
ChooseBoxData[Int](12,"some string"), /* also allow, because is ChooseBoxData[Int]*/
ChooseBoxData[Boolean](true,"some string")/* not allow type other than ChooseBoxData[String] or ChooseBoxData[Int]*/
)
Something like this maybe:
trait AllowableBoxData
object AllowableBoxData {
private of[T](cbd: ChooseBoxData[T]) = new ChooseBoxData(cbd.index, cbd.text)
with AllowableBoxData
implicit def ofInt(cbd: ChooseBoxData[Int]) = of(cbd)
implicit def ofString(cbd: ChooseBoxData[String]) = of(cbd)
}
Now you can do things like
val list: List[ChooseBoxData[_] with AllowableBoxData] = List(ChooseBoxData("foo", "bar"), ChooseBoxData(0, "baz")
But not val list: List[AllowableBoxData] = List(ChooseBoxData(false, "baz"))
Also, if you were looking to declare a function argument rather than just a variable, there would be a bit more elegant solution:
trait CanUse[T]
implicit case object CanUseInt extends CanUse[Int]
implicit case object CanUseString extends CanUse[String]
def foo[T : CanUse](bar: List[ChooseBoxData[T]])
Here's what I came up with:
First, we create the following Algebraic Data Types (ADT):
sealed trait StringInt
case class Stringy(s : String) extends StringInt
case class Inty(s : Int) extends StringInt
And define ChoooseBoxData as follows:
case class ChooseBoxData(index : StringInt, text : String)
Then we define the following implicts to convert Int and String in the scope to the defined ADT:
object CBImplicits {
implicit def conv(u : String) = Stringy(u)
implicit def conv2(u : Int) = Inty(u)
}
Now, we can enforce the requirement in the question. Here is an example:
import CBImplicits._
val list = List(ChooseBoxData("str", "text"),
ChooseBoxData(1, "text"),
ChooseBoxData(true, "text"))
Trying to run the above, the compiler will complain about type mismatch. But this will compile and run:
List(
ChooseBoxData("str", "text"),
ChooseBoxData(1, "text"),
ChooseBoxData(12, "text2"))
which results in:
a: List[ChooseBoxData] =
List(ChooseBoxData(Stringy(str),text), ChooseBoxData(Inty(1),text), ChooseBoxData(Inty(12),text2))
This preserves index type information (wrapped in StringInt supertype of course) which later can be easily extracted using pattern matching for individual elements.
It is easy to remove the wrapper for all elements too, but it will result in the index type to become Any which is what we would expect because Any is the lowest common ancestor for both String and Int in Scala's class hierarchy.
EDIT: A Solution Using Shapeless
import shapeless._
import syntax.typeable._
case class ChooseBoxData[T](index : T, text : String)
val a = ChooseBoxData(1, "txt")
val b = ChooseBoxData("str", "txt")
val c = ChooseBoxData(true, "txt")
val list = List(a, b, c)
val `ChooseBoxData[Int]` = TypeCase[ChooseBoxData[Int]]
val `ChooseBoxData[String]` = TypeCase[ChooseBoxData[String]]
val res = list.map {
case `ChooseBoxData[Int]`(u) => u
case `ChooseBoxData[String]`(u) => u
case _ => None
}
//result
res: List[Product with Serializable] = List(ChooseBoxData(1,txt), ChooseBoxData(str,txt), None)
So it allows compilation, but will replace invalid instances with None (which then can be used to throw a runtime error if desired), or you can directly filter the instances you want using:
list.flatMap(x => x.cast[ChooseBoxData[Int]])
//results in:
List[ChooseBoxData[Int]] = List(ChooseBoxData(1,txt))
You can build extra constraint on top of your case class.
import language.implicitConversions
case class ChooseBoxData[T](index:T, text:String)
trait MySpecialConstraint[T] {
def get: ChooseBoxData[T]
}
implicit def liftWithMySpecialConstraintString(cbd: ChooseBoxData[String]) =
new MySpecialConstraint[String] {
def get = cbd
}
implicit def liftWithMySpecialConstraintInt(cbd: ChooseBoxData[Int]) =
new MySpecialConstraint[Int] {
def get = cbd
}
// Now we can just use this constraint for out list
val l1: List[MySpecialConstraint[_]] = List(ChooseBoxData("A1", "B1"), ChooseBoxData(2, "B2"))
Why can't you do it like this:
object solution extends App {
case class ChooseBoxData[T](index: T, text: String) extends GenericType[T]
trait GenericType[T] {
def getType(index: T, text: String): ChooseBoxData[T] = ChooseBoxData[T](index, text)
}
val specialList = List(
ChooseBoxData[String]("some string", "some string"),
ChooseBoxData[Int](12, "some string"),
ChooseBoxData[Boolean](true, "some string")
)
println(specialList)
}
//output: List(ChooseBoxData(some string,some string), ChooseBoxData(12,some string), ChooseBoxData(true,some string))

Pattern matching on POJOs in Scala?

I'm trying to update some of my old Scala code to new APIs.
In one of the libraries I use, a case class has been converted to a simple POJO for compatibility reasons.
I was wondering if it is still possible somehow to use pattern matching for the Java class.
Imagine I have a simple Java class like:
public class A {
private int i;
public A(int i) {
this.i = i;
}
public int getI() {
return i;
}
}
After compilation, I would like to use it in pattern matching somehow like:
class Main extends App {
val a = ...
a match {
case _ # A(i) =>
println(i);
}
}
For the code above, I obviously get an error: Main.scala:7: error: object A is not a case class constructor, nor does it have an unapply/unapplySeq method.
Is there any trick I could use here?
Thanks in advance!
It's a little late in the night here for subtlety, but
object `package` {
val A = AX
}
object AX {
def unapply(a: A): Option[Int] = Some(a.getI)
}
object Test extends App {
Console println {
new A(42) match {
case A(i) => i
}
}
}
Write unapply yourself:
object A {
def unapply(x: A) = Some(x.getI)
}
#som-snytt's answer is correct - but if you are doing this just for e.g. pattern-matching then I prefer the more succinct approach:
import spray.httpx.{UnsuccessfulResponseException => UrUnsuccessfulResponseException}
object UnsuccessfulResponseException {
def unapply(a: UrUnsuccessfulResponseException): Option[HttpResponse]
= Some(a.response)
}
... match {
case Failure(UnsuccessfulResponseException(r)) => r
case ...
}
Ur is a pretentious way of saying "original", but it only takes two letters.

Collect arguments to apply to curried functions in Java/Scala

I would like to create a class in Java 8 which is able to recursively create an object which has a method that takes a function parameter based on the parameters I added.
For example, I would like to be able to do this:
new X().param(23).param("some String").param(someObject)
.apply((Integer a) -> (String b) -> (Object c) -> f(a,b,c))
The apply method would then apply the collected parameters to the given function.
I feel this should be possible without reflection while maintaing type-safety, but I can't quite figure out how. A solution in Scala is also welcome, if I can translate it to Java 8. If it's not possible, I'll also accept an answer that explains why.
What I have so far is essentially this:
class ParamCmd<A,X> {
final A param;
public ParamCmd(A param) {
this.param = param;
}
public<B> ParamCmd<B, Function<A,X>> param(B b) {
return new ParamCmd<>(b);
}
public void apply(Function<A,X> f) {
// this part is unclear to me
}
public static void main(String[] args) {
new ParamCmd<Integer,String>(0).param("oops").param(new Object())
// the constructed function parameters are reversed relative to declaration
.apply((Object c) -> (String b) -> (Integer a) ->
"args were " + a + " " + b + " " + c
);
}
}
As noted in the code comments, my problems are keeping the function parameters in the order of the calls of param(), and actually applying the parameters.
For an unlimited amount of parameters, the only solution I could think of is with Heterogeneous Lists in Scala.
It is probably isn't feasible in Java as there is type level computation going on with path-dependant types.
Using Heterogeneous Lists and Path-Dependant types:
import scala.language.higherKinds
object Main extends App {
val builder1 = HCons(23, HCons("Hello", HNil))
val builder2 = HCons(42L, builder1)
val res1:String = builder1.apply(i => s => i + s)
val res2:String = builder2.apply(l => i => s => (i+l) + s)
println(res1) // 23Hello
println(res2) // 65Hello
}
sealed trait HList {
type F[Res]
def apply[Res]: F[Res] => Res
}
case class HCons[Head, HTail <: HList](head: Head, tail: HTail) extends HList {
type F[Res] = Head => (tail.type)#F[Res]
def apply[Res]: F[Res] => Res = f => tail.apply(f(head))
}
case object HNil extends HList {
type F[Res] = Res
def apply[Res]: F[Res] => Res = identity
}
This code prints:
23Hello
65Hello
The second, more limited way of doing this, but which might work with Java, is to create multiple classes for each function length, which returns the next sized function length class wrapping the value, up to some maximal length - See the Applicative Builder in Scalaz: "Scalaz Applicative Builder"
This doesn't answer your question. However, maybe it helps someone to find a solution, or to explain why it isn't possible in Java and/or Scala.
It can be done in C++, with an arbitrary number of parameters, and without losing type-safety. The call-side look as follows. Unfortunately, the lambda syntax in C++ is quite verbose.
bar{}.param(23).param("some String").param(4.2).apply(
[](int i) {
return [=](std::string s) {
return [=](double d) {
std::cout << i << ' ' << s << ' ' << d << '\n';
};
};
});
Following is the definition of foo and bar. The implementation is straight-forward. However, I doubt that it is possible to build something like this in Java, because the way type parameters work in Java. Generics in Java can only be used to avoid type casts, and that's not enough for this use case.
template <typename Param, typename Tail>
struct foo {
Param _param;
Tail _tail;
template <typename P>
auto param(P p) {
return foo<P, foo>{p, *this};
}
template <typename Function>
auto apply(Function function) {
return _tail.apply(function)(_param);
}
};
struct bar {
template <typename P>
auto param(P p) {
return foo<P, bar>{p, *this};
}
template <typename Function>
auto apply(Function function) {
return function;
}
};
Sorry I just could give some leads in Scala:
Perhaps it would help to have a look at http://www.scala-lang.org/api/2.10.4/index.html#scala.Function$
.apply((Integer a) -> (String b) -> (Object c) -> f(a,b,c))
pretty much looks like Function.uncurried
param(23).param("some String").param(someObject)
could be implemented using a list for an accumulator if you don't care for Type safety. If you want to keep the Types you could use the HList out of Shapeless https://github.com/milessabin/shapeless which comes with a handy tuppled method.
Implementation of param():
import shapeless._
import HList._
import syntax.std.traversable._
class Method(val l : HList = HNil) {
def param(p: Any) = new Method( p :: l )
}
Example
scala> val m = new Method().param(1).param("test")
m: Method = Method#1130ad00
scala> m.l
res8: shapeless.HList = test :: 1 :: HNil

How to wrap an incremental mutable Java class in a functional Scala class without eagerly wasting memory?

[I created an imaginary JavaClass just to be able to test the code, see at the end of the question.]
I use an incremental/mutable algorithm from a Java library (Weka, but the question applies to any Java library). I am trying to wrap its mutable nature. One way to do it is like in code below:
class Model {
private val model = new JavaModel //just a fake example (could be NaiveBayes)
//just returns the JavaModel to simplify the question.
lazy val last_state(items: Seq[Item]) = {
items foreach model.update
model
}
}
The problem is that sometimes, some of the intermediary states are also needed.
The straight forward way to do this is to keep a copy of each of them:
class Model {
private val model = new JavaModel //just a fake example (could be NaiveBayes)
def states(items: Seq[Item]): Stream[JavaModel] =
if (items.isEmpty) Stream.Empty
else {
val h = items.head
val t = items.tail
val clone = clone(model) // (AbstractClassifier.makeCopy for weka users)
clone.update(h)
clone #:: states(t)
}
}
}
When one needs to get the last result, this is much slower than the first code because of all the unneeded copying. I could put lazy vals inside the stream. But at the time that its evaluation occurs, the instance model is not guaranteed to be the same anymore.
class Lazy (model: JavaModel) {
lazy val copy = clone(model) // (AbstractClassifier.makeCopy for weka users)
}
class Model {
private val model = new JavaModel //just a fake example (could be NaiveBayes)
def states(items: Seq[Item]): Stream[Lazy] =
if (items.isEmpty) Stream.Empty
else {
val h = items.head
val t = items.tail
model.update(h)
Lazy(model) #:: states(t)
}
}
}
This ugly solution was the best I found. I has non-private mutable fields, etc.:
class JavaClass(initial:Int = 1) {
//represents a lot of data structures
private var state = initial
//Int represents something more complex
def update(h: Int) {
println("Some heavy calculations performed. State=" + state)
state += 1
}
def copy = new JavaClass(state)
//other methods that make use of the state ...
}
case class Lazy(java_object: JavaClass) {
var lazy_var: Option[JavaClass] = null
def copied = if (lazy_var == null) {
lazy_var = Some(java_object.copy)
lazy_var
} else lazy_var
}
class Model {
def states(items: Seq[Int]): Stream[Lazy] = {
val java_class = new JavaClass
def rec(items: Seq[Int], laz: Lazy): Stream[Lazy] =
if (laz != null && items.isEmpty) Stream.Empty
else {
if (laz.lazy_var == null) laz.lazy_var = None
val h = items.head
val t = items.tail
java_class.update(h)
val new_laz = Lazy(java_class)
new_laz #:: rec(t, new_laz)
}
rec(items, Lazy(null))
}
}
//Test:
scala> val m = new Model
m: Model = Model#726b80fa
scala> val states = m.states(Seq(1, 2, 3, 4, 5))
Some heavy calculations performed. State=1
states: Stream[Lazy] = Stream(Lazy(JavaClass#283e1abf), ?)
scala> states(0).copied match {case Some(x) => x; case None => -1}
res31: Any = JavaClass#1029bf49
scala> states(3).copied match {case Some(x) => x; case None => -1}
Some heavy calculations performed. State=2
Some heavy calculations performed. State=3
Some heavy calculations performed. State=4
res32: Any = JavaClass#3cb40c69
scala> states(3).copied match {case Some(x) => x; case None => -1}
res33: Any = JavaClass#3cb40c69
scala> states(1).copied match {case Some(x) => x; case None => -1}
res34: Any = -1
A good place is to start from "artificial fields" using "_=" posfix as explained in the example from this site. Maybe it is better to open a new question with correct camelCase names.
// Fields may be artificial:
class H {
private var realX = 0
def x = realX
// called for "this.x = <value>":
def x_=(newX : Int) {
this.realX = newX
}
}

Categories