apply method is not being called - scala

I have a break point set at line s = new Array(capacity) but it seems like the apply method is not being called. Have I implemented it correctly ?
object StacksAndQueuesTest {
def main(args: Array[String]) {
val f = new FixedCapacityStackOfStrings(3)
println(f.isEmpty);
}
}
class FixedCapacityStackOfStrings(capacity : Int) {
var s : Array[String] = _
var N : Int = 0
def isEmpty : Boolean = {
N == 0
}
def push(item : String) = {
this.N = N + 1
s(N) = item
}
def pop = {
this.N = N - 1
val item : String = s(N)
/**
* Setting this object to null so
* that JVM garbage collection can clean it up
*/
s(N) = null
item
}
object FixedCapacityStackOfStrings {
def apply(capacity : Int){
s = new Array(capacity)
}
}
}

In your case the companion object may not be of much help except to avoid newoperator
class FixedCapacityStackOfStrings(capacity: Int) {
var s: Array[String] = new Array(capacity)
var N: Int = 0
def isEmpty: Boolean = {
N == 0
}
def push(item: String) = {
this.N = N + 1
s(N) = item
}
def pop = {
this.N = N - 1
val item: String = s(N)
/**
* Setting this object to null so
* that JVM garbage collection can clean it up
*/
s(N) = null
item
}
}
object FixedCapacityStackOfStrings {
def apply(capacity: Int) = {
println("Invoked apply()")
new FixedCapacityStackOfStrings(capacity)
}
def main(args: Array[String]){
val f = FixedCapacityStackOfStrings(5)
println(f)
}
}
And then you can use it like
val f = FixedCapacityStackOfStrings(5)

For the calling object 'FixedCapacityStackOfStrings' to see the .isEmpty method I needed to use :
def apply(capacity: Int) : FixedCapacityStackOfStrings = {
new FixedCapacityStackOfStrings(capacity)
}
instead of
def apply(capacity: Int) {
new FixedCapacityStackOfStrings(capacity)
}

Related

Is it possible to pass values from two instances of the same Scala class

Say I have this situation
class Pipe {
var vel = 3.4
var V = 300
var a = 10.2
var in = ???
var TotV = V+in
var out = TotV*a/vel
}
val pipe1 = new Pipe
val pipe2 = new Pipe
The in variable is were my problem is, what i'd like to do is get the out variable from pipe1 and feed that in as the in variable for pipe 2 effectively to join the two pipes but I cant figure out if this is even possible in the same class. So I can do it manually but need to know if its possible to do in the class.
pipe2.in = pipe1.out
my attempted fix was to add an ID field then try and use that to reference an instance with a higher id field but that doesnt seem doable. ie
class Pipe(id:Int) {
var vel = 3.4
var V = 300
var a = 10.2
var in = Pipe(id+1).out //this is the sticking point, I want to reference instances of this class and use their out value as in value for instances with a lower ID
var TotV = V+in
var out = TotV*a/vel
}
any help would be appreciated
You can do this by defining a companion object for the class and passing in the upstream pipe as an optional parameter to the factory method, then extracting its in value and passing it to the class constructor, as follows:
object Pipe {
def apply(upstreamPipe: Option[Pipe]): Pipe = {
val inValue = upstreamPipe match {
case Some(pipe) => pipe.out
case None => 0 // or whatever your default value is
new Pipe(inValue)
}
You would then call
val pipe1 = Pipe(None)
val pipe2 = Pipe(Some(pipe1))
Unfortunately your question is not clear now. Under certain assumptions what you describe looks like what is now called "FRP" aka "Functional Reactive Programming". If you want to do it in a serious way, you probably should take a look at some mature library such as RxScala or Monix that handle many important in the real world details such as error handling or scheduling/threading and many others.
For a simple task you might roll out a simple custom implementation like this:
trait Observable {
def subscribe(subscriber: Subscriber): RxConnection
}
trait RxConnection {
def disconnect(): Unit
}
trait Subscriber {
def onChanged(): Unit
}
trait RxOut[T] extends Observable {
def currentValue: Option[T]
}
class MulticastObservable extends Observable with Subscriber {
private val subscribers: mutable.Set[Subscriber] = mutable.HashSet()
override def onChanged(): Unit = subscribers.foreach(s => s.onChanged())
override def subscribe(subscriber: Subscriber): RxConnection = {
subscribers.add(subscriber)
new RxConnection {
override def disconnect(): Unit = subscribers.remove(subscriber)
}
}
}
abstract class BaseRxOut[T](private var _lastValue: Option[T]) extends RxOut[T] {
private val multicast = new MulticastObservable()
protected def lastValue: Option[T] = _lastValue
protected def lastValue_=(value: Option[T]): Unit = {
_lastValue = value
multicast.onChanged()
}
override def currentValue: Option[T] = lastValue
override def subscribe(subscriber: Subscriber): RxConnection = multicast.subscribe(subscriber)
}
class RxValue[T](initValue: T) extends BaseRxOut[T](Some(initValue)) {
def value: T = this.lastValue.get
def value_=(value: T): Unit = {
this.lastValue = Some(value)
}
}
trait InputConnector[T] {
def connectInput(input: RxOut[T]): RxConnection
}
class InputConnectorImpl[T] extends BaseRxOut[T](None) with InputConnector[T] {
val inputHolder = new RxValue[Option[(RxOut[T], RxConnection)]](None)
private def updateValue(): Unit = {
lastValue = for {inputWithDisconnect <- inputHolder.value
value <- inputWithDisconnect._1.currentValue}
yield value
}
override def connectInput(input: RxOut[T]): RxConnection = {
val current = inputHolder.value
if (current.exists(iwd => iwd._1 == input))
current.get._2
else {
current.foreach(iwd => iwd._2.disconnect())
inputHolder.value = Some(input, input.subscribe(() => this.updateValue()))
updateValue()
new RxConnection {
override def disconnect(): Unit = {
if (inputHolder.value.exists(iwd => iwd._1 == input)) {
inputHolder.value.foreach(iwd => iwd._2.disconnect())
inputHolder.value = None
updateValue()
}
}
}
}
}
}
abstract class BaseRxCalculation[Out] extends BaseRxOut[Out](None) {
protected def registerConnectors(connectors: InputConnectorImpl[_]*): Unit = {
connectors.foreach(c => c.subscribe(() => this.recalculate()))
}
private def recalculate(): Unit = {
var newValue = calculateOutput()
if (newValue != lastValue) {
lastValue = newValue
}
}
protected def calculateOutput(): Option[Out]
}
case class RxCalculation1[In1, Out](func: Function1[In1, Out]) extends BaseRxCalculation[Out] {
private val conn1Impl = new InputConnectorImpl[In1]
def conn1: InputConnector[In1] = conn1Impl // show to the outer world only InputConnector
registerConnectors(conn1Impl)
override protected def calculateOutput(): Option[Out] = {
for {v1 <- conn1Impl.currentValue}
yield func(v1)
}
}
case class RxCalculation2[In1, In2, Out](func: Function2[In1, In2, Out]) extends BaseRxCalculation[Out] {
private val conn1Impl = new InputConnectorImpl[In1]
def conn1: InputConnector[In1] = conn1Impl // show to the outer world only InputConnector
private val conn2Impl = new InputConnectorImpl[In2]
def conn2: InputConnector[In2] = conn2Impl // show to the outer world only InputConnector
registerConnectors(conn1Impl, conn2Impl)
override protected def calculateOutput(): Option[Out] = {
for {v1 <- conn1Impl.currentValue
v2 <- conn2Impl.currentValue}
yield func(v1, v2)
}
}
// add more RxCalculationN if needed
And you can use it like this:
def test(): Unit = {
val pipe2 = new RxCalculation1((in: Double) => {
println(s"in = $in")
val vel = 3.4
val V = 300
val a = 10.2
val TotV = V + in
TotV * a / vel
})
val in1 = new RxValue(2.0)
println(pipe2.currentValue)
val conn1 = pipe2.conn1.connectInput(in1)
println(pipe2.currentValue)
in1.value = 3.0
println(pipe2.currentValue)
conn1.disconnect()
println(pipe2.currentValue)
}
which prints
None
in = 2.0
Some(905.9999999999999)
in = 3.0
Some(909.0)
None
Here your "pipe" is RxCalculation1 (or other RxCalculationN) which wraps a function and you can "connect" and "disconnect" other "pipes" or just "values" to various inputs and start a chain of updates.

How to implement class that supports circular iteration and deletion

I have a class, that should support circular iteration and deletion:
class CircularTest {
private val set = mutable.LinkedHashSet[String]("1", "2", "3", "4", "5")
private val circularIter: Iterator[String] = Iterator.continually(set).flatten
def selectNext: String = {
circularIter.next()
}
def remove(v: String): Unit = {
set.remove(v)
}
}
And this not working.
Simple test, that should work:
val circularTest = new CircularTest
circularTest.selectNext shouldEqual "1"
circularTest.selectNext shouldEqual "2"
circularTest.remove("3")
circularTest.remove("5")
circularTest.selectNext shouldEqual "4" // actual "3"
circularTest.selectNext shouldEqual "1"
How to implement this functionality? Or maybe other solution with no iterator?
Well... The thing is that the Iterator.continually will give you a kind of immutable thing in this case. Which means that even if you change the content of your set it will have no effect on iterator.
You can actually have a work around that with updating the iterator itself in the remove method.
class CircularTest {
private var set = Set[String]("1", "2", "3", "4", "5")
private var circularIter: Iterator[String] = Iterator.continually(set).flatten
def selectNext: String = this.synchronized {
circularIter.next()
}
def remove(v: String): Unit = this.synchronized {
set = set.remove(v)
circularIter = Iterator.continually(set).flatten
}
}
But a better approach is to actually implement your own iterator in proper way.
import scala.collection.immutable.HashSet
import scala.collection.mutable.ArrayBuffer
class MyCircularIterator[T] extends Iterator[T] {
private var index: Int = 0
private var set: mutable.LinkedHashSet[T] = mutable.LinkedHashSet()
private var vector: Vector[T] = Vector()
private var vectorSize: Int = 0
override def hasNext: Boolean = this.synchronized {
set.size match {
case 0 => false
case _ => true
}
}
// Iterator does not define `next()` behavior whe hasNext == false;
// here it will just throw IndexOutOfBoundsException
override def next(): T = this.synchronized {
index = index % vectorSize
val next = vector(index)
index = index + 1
next
}
def add(t: T*): Unit = this.synchronized {
set = set ++ t
vector = Vector(set.toList: _*)
vectorSize = vector.length
}
def remove(t: T*): Unit = this.synchronized {
set = set -- t
vector = Vector(set.toList: _*)
vectorSize = vector.length
}
}
object MyCircularIterator {
def apply[T](hashSet: HashSet[T]): MyCircularIterator[T] = {
val iter = new MyCircularIterator[T]()
iter.add(hashSet.toList: _*)
iter
}
}
Now you can use it like this,
val myCircularIterator = MyCircularIterator(HashSet[Int](1, 2, 3, 4, 5))
myCircularIterator.next()
// 1
myCircularIterator.next()
// 2
myCircularIterator.remove(3, 5)
myCircularIterator.next()
// 4
myCircularIterator.next()
// 1

scala trait members and derivated variables

Hi am trying to write a simple hill climbing algorithm in scala .
I have State and HillClimbing that are traits.
I define them as concrete classes when I apply them to the Graph problem.
In GraphHillClimbing I receive two errors. This is because I use GraphState instead of State (observe that GraphState is also a State).
How can I solve this?
trait State {
val loc = 0
def neighbours: List[State]
def get_loc():Int = return loc
}
class GraphState(loc:Int, g: Map[Int, List[Int]]) extends State {
def neighbours():List[GraphState] =
{
def neighboursAcc(l:List[Int], acc:List[GraphState], g:Map[Int, List[Int]]):List[GraphState] =
{
if(l.isEmpty) acc
else {
val new_neig = new GraphState(l.head, g)
neighboursAcc(l.tail, List(new_neig) ++ acc, g)
}
}
neighboursAcc(g(loc), List(), g)
}
}
trait HillClimbing {
val max_iteration = 4
val start:State
def cost(state:State):Double
private def argmin(costs:List[Double]):Int = {
val best = costs.min
costs.indexOf(best)
}
private def next_best(states:List[State]):State = {
val costs = states map(x => cost(x))
val pos = argmin(costs)
states(pos)
}
def minimize():State = {
def minimizeAcc(iteration:Int, state:State):State =
{
if(iteration > max_iteration) state
else {
val neigs = state.neighbours
val next_state = next_best(neigs)
minimizeAcc(iteration+1, next_state)
}
}
minimizeAcc(0, start)
}
}
class GraphHillClimbing(start:GraphState, goal:GraphState) extends HillClimbing {
// ERROR 1 = start was State and now it is GraphState
// ERROR 2 = cost should take a State
def cost(current_state:GraphState):Double = {
val distance = goal.get_loc() - current_state.get_loc()
if(distance > 0 ) distance
else -distance
}
}
object RunHillClimbing {
def main(args: Array[String]) {
val G = Map[Int, List[Int]](1->List(2, 4, 5), 2->List(1, 3, 4), 3->List(2, 6), 4->List(1, 2, 5), 5->List(1, 4), 6->List(3))
val start = new GraphState(1, G)
val goal = new GraphState(6, G)
val hc = new GraphHillClimbing(start, goal)
print(hc.minimize())
}
}
I think this can be solved using some type parameters with type bounds.
Also in your constructor for GraphHillClimbing you should use val to indicate that the parameter start is the concrete implementation of the abstract start.
trait State[+Self] {
Self =>
def loc:Int
def neighbours: List[Self]
def get_loc():Int = return loc
}
class GraphState(val loc:Int, g: Map[Int, List[Int]]) extends State[GraphState] {
def neighbours():List[GraphState] =
{
def neighboursAcc(l:List[Int], acc:List[GraphState], g:Map[Int, List[Int]]):List[GraphState] =
{
if(l.isEmpty) acc
else {
val new_neig = new GraphState(l.head, g)
neighboursAcc(l.tail, List(new_neig) ++ acc, g)
}
}
neighboursAcc(g(loc), List(), g)
}
}
trait HillClimbing[T<:State[T]] {
val max_iteration = 4
val start:T
def cost(state:T):Double
private def argmin(costs:List[Double]):Int = {
val best = costs.min
costs.indexOf(best)
}
private def next_best(states:List[T]):T = {
val costs = states map(x => cost(x))
val pos = argmin(costs)
states(pos)
}
def minimize():T = {
def minimizeAcc(iteration:Int, state:T):T =
{
if(iteration > max_iteration) state
else {
val neigs = state.neighbours
val next_state = next_best(neigs)
minimizeAcc(iteration+1, next_state)
}
}
minimizeAcc(0, start)
}
}
class GraphHillClimbing(val start:GraphState, goal:GraphState) extends HillClimbing[GraphState] {
def cost(current_state:GraphState):Double = {
val distance = goal.get_loc() - current_state.get_loc()
if(distance > 0 ) distance
else -distance
}
}
object RunHillClimbing {
def main(args: Array[String]) {
val G = Map[Int, List[Int]](1->List(2, 4, 5), 2->List(1, 3, 4), 3->List(2, 6), 4->List(1, 2, 5), 5->List(1, 4), 6->List(3))
val start = new GraphState(1, G)
val goal = new GraphState(6, G)
val hc = new GraphHillClimbing(start, goal)
print(hc.minimize())
}
}
What I get:
error: class GraphHillClimbing needs to be abstract, since:
it has 2 unimplemented members.
/** As seen from class GraphHillClimbing, the missing signatures are as follows.
* For convenience, these are usable as stub implementations.
*/
def cost(state: this.State): Double = ???
val start: this.State = ???
class GraphHillClimbing(start:GraphState, goal:GraphState) extends HillClimbing {
^
Replace GraphState in the class with State, because inheritance
demands you'll have to handle State not GraphState.
Then replace
val loc = 0
with
def loc = 0
So you can overwrite it in GraphState.

Is it possible and how to have var that can only be set once?

Is there a native way to make sure that a variable can only be set once?
Currently, I am using this approach
class SetOnceVariable[T]
{
private var value : T = _
private var initialized = false
def apply(_v : T = _) : T =
{
if (value != null && !initialized) {
value = _v
initialized = true
}
value
}
}
class ClientInfo
{
val userIP : SetOnceVariable[String] = new SetOnceVariable[String]
}
There's no such language construct, but I think I can clean up your code, at least.
class SetOnce[A](var toOption: Option[A] = None) {
def set(a: A): Unit = if (toOption.isEmpty) toOption = Some(a)
def get: A = toOption.get
}
Usage:
val x = new SetOnce[Int]
x.toOption // None
x.set(1)
x.get // 1
x.set(2)
x.get // 1
I omitted the null consideration because idiomatic Scala code tends to not use or consider null outside of Java compatibility. We mostly pretend that it doesn't exist.
Approach using lazy:
class SetOnceVariable[T] {
private var v: T = _
private lazy val value: T = v
def apply(_v: T = ???): T = {
v = _v
value
}
}
val info = new ClientInfo
println(info.userIP("IP")) // IP
println(info.userIP("IP2")) // IP
println(info.userIP("IP3")) // IP
To make it threadsafe you can use:
def apply(_v: T = ???): T =
synchronized {
v = _v
value
}
You can create a constant variable by using a val. For instance:
val a = 0; // Cannot be changed
var b = 0; // Can be changed
See this answer for more details: https://stackoverflow.com/a/1792207/4380308
Edit:
A val can be declared and then initialized later as well.
val a;
a = 0;
You can try the following:
class varSingleton[A >: Null <: AnyRef] {
private[this] var _a = null: A
def :=(a: A) { if (_a eq null) _a = a else throw new IllegalStateException }
def apply() = if (_a eq null) throw new IllegalStateException else _a
}
You can use this further like:
var singleVal = new varSingleton[Integer]
singleVal := 12
singleVal() // returns 12
singleVal := 13 //IllegalStateException
you can use simple getter and setter:
class ClientInfo {
private var _userIP: Option[String] = None
def userIP: String = _userIP.get
def userIP_=(value: String): Unit = {
_userIP = _userIP.orElse(Option(value))
}
}
val clientInfo = new ClientInfo() //> clientInfo : controllers.stackoverflow.ClientInfo controllers.stackoverflow$Clien
//| tInfo#4fccd51b
clientInfo.userIP = "first"
clientInfo.userIP //> res0: String = first
clientInfo.userIP = "second"
clientInfo.userIP //> res1: String = first
I prefer to use Option that the value directly to prevent nulls and NPE. You can of course add what ever logic you need in the setter.

Setting instance vars with apply

With Array it's possible to get and set elements with val i = xs(0) and xs(0) = i syntax. How to implement this functionality in my own class? So far I was only able to implement getting the values.
class Matrix(val m : Int, val n : Int) {
val matrix = Array.ofDim[Double](m, n)
def apply(i:Int)(j:Int) = matrix(i)(j)
}
UPDATE: Thanks to Mauricio for answer about update method. That's the final version
class Matrix(val m:Int, val n:Int) {
private val matrix = Array.ofDim[Double](m, n)
def apply(i:Int) = new {
def apply(j:Int) = matrix(i)(j)
def update(j:Int, v:Double) = { matrix(i)(j) = v }
}
}
it("matrix") {
val m = new Matrix(3, 3)
m(0)(1) = 10.0
val x = m(0)(1)
x should equal(10.0)
x.isNegInfinity should be (false) // Implicits for Double work!
}
You need to declare an update method:
class Matrix(val m : Int, val n : Int) {
private val matrix = Array.ofDim[Double](m, n)
def apply(i:Int)(j:Int) = matrix(i)(j)
def update( i : Int, j : Int, value : Double) {
matrix(i)(j) = value
}
}
val m = new Matrix( 10, 10 )
m(9, 9) = 50