Correct method signature for RichGroupReduceFunction? - scala

The below extended class of RichGroupReduceFunction, does not compile. The signature seemingly does not match the interface. I can't tell the difference.
class SPointReduce extends RichGroupReduceFunction[Int, Int] {
override def reduce (
values: Iterable[Int],
out: Collector[Int]): Unit = {
values.foreach {
value: Int =>
out.collect(value)
}
}
}
The compiler reports:
Error:(62, 16) method reduce overrides nothing.
Note: the super classes of class SPointReduce contain the
following, non final members named reduce: def reduce(x$1:
Iterable[Nothing],x$2: org.apache.flink.util.Collector[Nothing]): Unit
override def reduce (

You have to make sure that you import the java.lang.Iterable when you override the reduce method of RichGroupReduceFunction. Otherwise, you will get the above mentioned error.

Related

Type class pattern: simulacrum boosted method not found

I have a requirement to be able to count number of times AtomicReference[V].get is called in a class that has as field an array of wildcarded atomic references.
To that end, first, I've extended java's AtomicReference[V]:
import java.util.concurrent.atomic.{AtomicInteger => AInt, AtomicReference => ARef}
class MyAtomicReference[V] extends ARef[V]{
private val getCounter: AInt = new AInt(0)
def getAndListen(): V = {
getCounter.getAndIncrement()
super.get()
}
def counter(): Int = getCounter.get()
def resetCounter(): Unit = getCounter.set(0)
}
Then I've added trait AtomicRefCounter which declares the method that I would wish to invoke:
import simulacrum.typeclass
#typeclass trait AtomicRefCounter [R[_], T] {
def countGets(container: R[T]): Int
}
Lastly, I've defined a default AtomicArrayRefCounter in the object DefaultAtomicRefCounters:
object DefaultAtomicRefCounters {
implicit val arrayOfAtomicsTraverser = new AtomicRefCounter[Array, MyAtomicReference[_]] {
override def countGets(container: Array[MyAtomicReference[_]]): Int = container map(_.counter()) sum
}
}
Despite that when I try to call the traverseAtomics() on a corresponding array in a test, I do not see it (I am using Intellij IDEA):
behavior of "removeO1"
"method" should "remove an element from the pool with time O(1)" in new IntPoolBuilder {
import org.learningconcurrency.traditional_concurrency.helpers.DefaultAtomicRefCounters._
pool.buckets.countGet
}
A piece of advice on what I am missing would really help. Usage of simulacrum is not mandatory - if you feel you know how to solve this without it, I would love to hear that.
update:
This is how the buckets are implemented:
class Pool[T] {
type TimeStampedList = (List[T], Long)
val parallelism: Int = Runtime.getRuntime.availableProcessors * 32
val buckets = new Array[MyAtomicReference[TimeStampedList]](parallelism)
...
I think, you might have gotten wrong how implicits work.
If I read everything correctly, then in your code
implicitly[AtomicRefCounter[Array, MyAtomicReference[_]]].countGets(pool.buckets)
should work.
I you wanted to call countGets on the Array you should use the EnrichMyLibrary pattern.
object DefaultAtomicRefCounters {
implicit class RichArray(private underlying: Array[MyAtomicReference[_]] extends AnyVal {
def countGets: Int = underlying.map(_.counter()).sum
}
}
As disappointing as it is, I couldn't make it work with simulacrum annotation, so I've followed Sascha's advise. I just modified slightly his second example (I couldn't get it to work with implictly) so it compiles and works:
object TraditionalConcurrencyHelpers {
implicit class CountArrayAtomicGetsOps(wrapper: Array[MyAtomicReference[(List[Int], Long)]]) {
def countGets()(implicit atomicRefCounter: AtomicRefCounter[Array, MyAtomicReference[(List[Int], Long)]]): Int = atomicRefCounter.countGets(wrapper)
}
}
With this I have no problem calling countGets on the array:
behavior of "removeO1"
"method" should "remove an element from the pool with time O(1)" in new IntPoolBuilder {
import TraditionalConcurrencyHelpers._
import org.learningconcurrency.traditional_concurrency.helpers.DefaultAtomicRefCounters._
//call pool.removeO1 (not implemented yet)
pool.buckets.countGets() shouldEqual 1
}

scala typing require implicit

I'm trying to build following
I have a parent generic class
abstract class ResultProvider[+T: Writes](db: DB) {
def get(id: Long): Future[Seq[T]]
}
And some implementations, e.g.
class LengthProvider(db: DB) extends ResultProvider[LengthResult](db){
override def get (userId: Long): Future[Seq[LengthResult]] = ...
}
object LengthProvider extends ((DB) => DisciplinePredictor) {
override def apply(db: DB) = new LengthProvider(db)
}
I have following configuration map:
val providers: Map[String, ((DB) => ResultProvider[???])] = Map(
"length" -> LengthProvider,
"width" -> WidthProvider,
...
)
My question is what should I put in place of ???. Ideally, it should be something like T : Writes, as I only care that this type has Writes implicit implemented, as I'm going to Json.toJson it. It will compile with Any, but then the information that the class should implement Writes implicit is lost.
Or should I use a different approach? I could probably create a superclass for all my result case classes (e.g.LengthResult), but I want to get away with the implicits.
You should be able to write ResultProvider[_] (search for "existential types" if you are unfamiliar with this syntax), but you'll need to give a name to the implicit:
abstract class ResultProvider[+T](db: DB)(implicit val writes: Writes[T]) { ... }
Elsewhere:
val provider: ResultProvider[_] = providers("length")
import provider.writes // makes the implicit visible here
...
You might need to help the compiler (or yourself, if you need to name the type) by providing a type variable:
providers("length") match {
case provider: ResultProvider[a] =>
import provider.writes
...
}

Accessibility of primary constructor parameters in scala

I am having hard time to understand the concept of primary constructor and it's parameters. What I have understood till now is: if we define a class as following
class Example(a: Int, b: Int)
Scala compiler generates a primary constructor of the class Examples with the above two parameters. But, it doesn't defines fields a and b in the class Example's definition. But if we define
class Example(val a: Int, val b: Int)
scala compiler generates the primary constructor as above and adds two fields in the class definition.
Now the problem comes when I am trying an example like
class PrimaryConstructor(a: Int, b: Int){
override def toString() = "PrimaryConstructor(" + this.a + ", " + this.b + ")"
}
The above code compiles well even if there is no fields named either a or b. I am not able to understand that if there are no any fields as such then how I am able to access them using this: the current object reference.
object Main{
def main(args: Array[String]){
val primaryConstructor = new PrimaryConstructor(1, 2)
println(primaryConstructor.a)
}
}
While if I try to access them from out side the class definition as above, I get the following error message after compilation.
error: value a is not a member of PrimaryConstructor
println(primaryConstructor.a)
I can understand this. But, how can I access those fields using this? Please help me to understand this.
It basically generates a private val, so
class A(a:Int) {
def func = a
}
and
class A(private[this] val a:Int) {
def func = a
}
are equivalent. This may not be entirely true if you omit the function.
When a constructor parameter is referred outside the constructor body ( such as in example func above ), Scala generates a private[this] val, otherwise not.
You can check scala spec for more details or look at this stackoverflow question
Martin's answer is great:
It basically generates a private val, so
class A(a:Int) {
def func = a
}
and
class A(private[this] val a:Int) {
def func = a
}
are equivalent and you can access a from inside your class.
But, note that class A(a: Int) means that the field a is instance private. Meaning that you cannot write something like this:
class A(a: Int){
def sum(other: A): Int = {
this.a + other.a
}
}
other.a is not allowed even though both instances are of the same type. You can only use this.a.

Scala compilation error

Can't figure out what's wrong with StrangeIntQueue extending Queue, why there is an error "Not enough arguments for constructor Queue: (leading: Int)list.Lister.Queue[Int]. Unspecified value parameter leading". How can I specify it?
class Queue[+T](
private val leading: T
) {
def enqueue[U >: T](x: U) =
new Queue[U](leading: U) // ...
}
class StrangeIntQueue(private val leading: Int) extends Queue[Int] {
override def enqueue(x: Int) = {
println(math.sqrt(x))
super.enqueue(x)
}
}
extends Queue[Int](leading)
You have to pass on the arguments even if it seems "obvious" what to do.
Note also that since you have declared leading private, you'll actually get two copies: one for StrangeIntQueue and one for Queue. (Otherwise you could have just StrangeIntQueue(leading0: Int) extends Queue[Int](leading0) and use the inherited copy of leading inside.)
The primary constructor of class Queue, which StrangeIntQueue extends, takes a parameter, but you're not passing it anything for the parameter. Try this:
class StrangeIntQueue(leading: Int) extends Queue[Int](leading) {
// ...
}

Inheritance and initialization in Scala

I have two Scala classes that look like this (paraphrased):
abstract class GenericParser[T] {
val lineFilter : String => Boolean
parseData()
def parseData() : T {
for( line <- .... if lineFilter(line) )
// do things
}
}
class SalesParser extends GenericParser[SalesRow] {
val lineFilter = line => !line.startsWith("//")
// ....
}
The problem is that lineFilter is null in parseData, presumably because parseData is called while the primary GenericParser constructor is still running, so the subclass hasn't fully initialized its members.
I can work around this by making lineFilter a def instead of a val, but is this expected behavior? It doesn't seem right that this problem should only become apparent after getting an NPE at runtime.
It is indeed the expected behavior, and is exactly the same problem as in this question:
Scala 2.8: how to initialize child class
You can basically copy-paste the answer form that question. Solutions include:
def or lazy val instead of val
early initialization of lineFilter
redesign of your classes to avoid the “virtual method call from superclass's constructor which accesses uninitialized subclass values” problem. For instance, why would you want to store the filter function in a val or return in from a def, while it could be implemented as a method?
abstract class GenericParser[T] {
def lineFilter(line: String): Boolean
parseData()
def parseData() : T {
for( line <- .... if lineFilter(line) )
// do things
}
}
class SalesParser extends GenericParser[SalesRow] {
def lineFilter(line: String) = !line.startsWith("//")
}