Scala Mutable Option? - scala

I want something like this:
private val cachedResponse = mutable.Option.empty[A]
def get: A = cachedResponse getOrElseUpdate db.findModel()
def update: Unit = {
db.updateModel
cachedResponse.empty() // set it to None/Option.empty
}
I am not looking for a generic HashMap based memoization like this. I tried implementing it using a var Option[A] but it did not look very idiomatic to me:
private var cachedResponse: Option[A] = None
def get: A = cachedResponse getOrElse {
cachedResponse = Option(db.findModel())
cachedResponse.get
}
def update: Unit = {
db.updateModel
cachedResponse = None
}

There isn't one built into the standard library.
Using a var containing an immutable Option is the idiomatic way to do it (assuming you can't rewrite this to not use state at all).
Otherwise, you should build your own. Here's the core of an implementation:
class MutableOpt[A] {
private[this] var myValue: A = _
private[this] var loaded = false
private def valueEquals(o: Any) = myValue == o
def get = if (loaded) myValue else throw new NoSuchElementException("MutableOpt")
def set(a: A): this.type = { loaded = true; myValue = a; this }
def getOrSet(a: => A): A = {
if (!loaded) {
myValue = a
loaded = true
}
myValue
}
def isEmpty = !loaded
def nonEmpty = loaded
def foreach[U](f: A => U): Unit = if (loaded) f(myValue)
def transform(f: A => A): this.type = { if (loaded) myValue = f(myValue); this }
def clear(): this.type = { loaded = false; this }
def toOption = if (loaded) Some(myValue) else None
override def toString = if (loaded) "MutableOpt("+myValue.toString+")" else "MutableOpt()"
override def hashCode = if (loaded) myValue.hashCode else 1751
override def equals(o: Any) = o match {
case m: MutableOpt[_] =>
(isEmpty && m.isEmpty) || (nonEmpty && m.nonEmpty && m.valueEquals(myValue))
case _ => false
}
}
object MutableOpt {
def from[A](o: Option[A]) = {
val m = new MutableOpt[A]
o match {
case Some(a) => m set a
case _ =>
}
m
}
}
Define together with :paste if using the REPL.

Related

In Scala, how to deal with heterogeneous list of the same parameterized type

I have an array of Any (in real life, it's a Spark Row, but it's sufficient to isolate the problem)
object Row {
val buffer : Array[Any] = Array(42, 21, true)
}
And I want to apply some operations on its elements.
So, I've defined a simple ADT to define a compute operation on a type A
trait Op[A] {
def cast(a: Any) : A = a.asInstanceOf[A]
def compute(a: A) : A
}
case object Count extends Op[Int] {
override def compute(a: Int): Int = a + 1
}
case object Exist extends Op[Boolean] {
override def compute(a: Boolean): Boolean = a
}
Given that I have a list of all operations and I know which operation is to apply to each element, let's use these operations.
object GenericsOp {
import Row._
val ops = Seq(Count, Exist)
def compute() = {
buffer(0) = ops(0).compute(ops(0).cast(buffer(0)))
buffer(1) = ops(0).compute(ops(0).cast(buffer(1)))
buffer(2) = ops(1).compute(ops(1).cast(buffer(2)))
}
}
By design, for a given op, types are aligned between cast and combine. But unfortunately the following code does not compile. The error is
Type mismatch, expected: _$1, actual: AnyVal
Is there a way to make it work ?
I've found a workaround by using abstract type member instead of type parameter.
object AbstractOp extends App {
import Row._
trait Op {
type A
def compute(a: A) : A
}
case object Count extends Op {
type A = Int
override def compute(a: Int): Int = a + 1
}
case object Exist extends Op {
type A = Boolean
override def compute(a: Boolean): Boolean = a
}
val ops = Seq(Count, Exist)
def compute() = {
val op0 = ops(0)
val op1 = ops(1)
buffer(0) = ops(0).compute(buffer(0).asInstanceOf[op0.A])
buffer(1) = ops(0).compute(buffer(1).asInstanceOf[op0.A])
buffer(2) = ops(1).compute(buffer(2).asInstanceOf[op1.A])
}
}
Is there a better way ?
It seems that your code can be simplified by making Op[A] extend Any => A:
trait Op[A] extends (Any => A) {
def cast(a: Any) : A = a.asInstanceOf[A]
def compute(a: A) : A
def apply(a: Any): A = compute(cast(a))
}
case object Count extends Op[Int] {
override def compute(a: Int): Int = a + 1
}
case object Exist extends Op[Boolean] {
override def compute(a: Boolean): Boolean = a
}
object AbstractOp {
val buffer: Array[Any] = Array(42, 21, true)
val ops: Array[Op[_]] = Array(Count, Count, Exist)
def main(args: Array[String]): Unit = {
for (i <- 0 until buffer.size) {
buffer(i) = ops(i)(buffer(i))
}
println(buffer.mkString("[", ",", "]"))
}
}
Since it's asInstanceOf everywhere anyway, it does not make the code any less safe than what you had previously.
Update
If you cannot change the Op interface, then invoking cast and compute is a bit more cumbersome, but still possible:
trait Op[A] {
def cast(a: Any) : A = a.asInstanceOf[A]
def compute(a: A) : A
}
case object Count extends Op[Int] {
override def compute(a: Int): Int = a + 1
}
case object Exist extends Op[Boolean] {
override def compute(a: Boolean): Boolean = a
}
object AbstractOp {
val buffer: Array[Any] = Array(42, 21, true)
val ops: Array[Op[_]] = Array(Count, Count, Exist)
def main(args: Array[String]): Unit = {
for (i <- 0 until buffer.size) {
buffer(i) = ops(i) match {
case op: Op[t] => op.compute(op.cast(buffer(i)))
}
}
println(buffer.mkString("[", ",", "]"))
}
}
Note the ops(i) match { case op: Opt[t] => ... } part with a type-parameter in the pattern: this allows us to make sure that cast returns a t that is accepted by compute.
As a more general solution than Andrey Tyukin's, you can define the method outside Op, so it works even if Op can't be modified:
def apply[A](op: Op[A], x: Any) = op.compute(op.cast(x))
buffer(0) = apply(ops(0), buffer(0))

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.

Combine two functions under the same name without overloading

Here is the code:
def transform1(f: String => String): Unit = {
val s = getString
f.andThen(putString)(s)
}
def transform2(f: String => Option[String]): Unit = {
val s = getString
f(s).foreach(putString(_))
}
How do you express these two ideas in one single function?
Method overloading does not work and seems discouraged by the community.
I didn't understand that why anyone may want this but here is a way to do it:
def transform(f: Either[(String => String), (String => Option[String])]: Unit = f match {
case Left(f) => // do transform1 here
case Right(f) => //do transform2 here
}
As I said at the begining you probably shouldn't want to do this; perhaps you should directly ask what you want.
The pattern to avoid overloading is to convert disparate arguments to a common, specific type. There could be any number of such conversions.
Not sure this is the most compelling example, however.
object X {
trait MapFlat[-A, +B] { def apply(x: A): B }
implicit class mapper[A](val f: A => A) extends MapFlat[A, A] {
override def apply(x: A) = {
val res = f(x)
println(res)
res
}
}
implicit class flatmapper[A](val f: A => Option[A]) extends MapFlat[A, Option[A]] {
override def apply(x: A) = {
val res = f(x)
res foreach println
res
}
}
def f[B](g: MapFlat[String, B]) = {
g("abc")
}
}
object Test extends App {
import X._
f((s: String) => s)
f((s: String) => Some(s))
}
One way to do it will be type classes, here's a sample -
trait Transformer[T] {
def transform(foo: String => T)
}
object Transformer {
implicit object StringTransformer extends Transformer[String] {
override def transform(foo: (String) => String): Unit = ??? // Your logic here
}
implicit object OptStringTransformer extends Transformer[Option[String]] {
override def transform(foo: (String) => Option[String]): Unit = ??? // Your logic here
}
}
class SampleClass {
def theOneTransformYouWant[T: Transformer](f: String => T) = {
implicitly[Transformer[T]].transform(f)
}
def canUseBothWays(): Unit = {
theOneTransformYouWant((s: String) => s)
theOneTransformYouWant((s: String) => Some(s))
}
}
Another way would be the magnet pattern
http://spray.io/blog/2012-12-13-the-magnet-pattern/
sealed trait TransformationMagnet {
def apply(): Unit
}
object TransformationMagnet {
implicit def fromString(f: String => String): TransformationMagnet =
new TransformationMagnet {
def apply(): Unit = ??? // Your code goes here
}
implicit def fromOptString(f: String => Option[String]): TransformationMagnet =
new TransformationMagnet {
def apply(): Unit = ??? // your code goes here
}
}
class SampleClass {
def theOneTransformYouWant(f: TransformationMagnet) = {
???
}
def hereWeUseItInBothWays(): Unit = {
theOneTransformYouWant((s: String) => s)
theOneTransformYouWant((s: String) => Some(s))
}
}
add a new parameter on the description typeOfTransform
add a conditional inside the function
if (typeOfTransform == type1){
//functionality1
}else {
//functionality2
}
Just for completeness, you can actually overload methods like this by adding implicit arguments which will always be available:
def transform(f: String => Option[String]): Unit = ...
def transform(f: String => String)(implicit d: DummyImplicit): Unit = ...

What's point in receiving a `PrefixMap` and returning a empty `PrefixMap`?

Here is an example from the stairway book:
object Example1 {
import collection._
class PrefixMap[T]
extends mutable.Map[String, T]
with mutable.MapLike[String, T, PrefixMap[T]] {
var suffixes: immutable.Map[Char, PrefixMap[T]] = Map.empty
var value: Option[T] = None
def get(s: String): Option[T] = {
// base case, you are at the root
if (s.isEmpty) value
// recursive
else suffixes get (s(0)) flatMap (_.get(s substring 1))
}
def iterator: Iterator[(String, T)] = {
(for (v <- value.iterator) yield ("", v)) ++
(for ((chr, m) <- suffixes.iterator; (s, v) <- m.iterator) yield (chr +: s, v))
}
def +=(kv: (String, T)): this.type = {
update(kv._1, kv._2)
this
}
def -=(key: String): this.type = {
remove(key)
this
}
def withPrefix(s: String): PrefixMap[T] = {
if (s.isEmpty) this
else {
val leading = s(0)
suffixes get leading match {
case None => {
// key does not exist, create it
suffixes = suffixes + (leading -> empty)
}
case _ =>
}
// recursion
suffixes(leading) withPrefix (s substring 1)
}
}
override def update(s: String, elem: T) = {
withPrefix(s).value = Some(elem)
}
override def remove(key: String): Option[T] = {
if (key.isEmpty) {
// base case. you are at the root
val prev = value
value = None
prev
} else {
// recursive
suffixes get key(0) flatMap (_.remove(key substring 1))
}
}
override def empty = PrefixMap.empty
}
import collection.mutable.{Builder, MapBuilder}
import collection.generic.CanBuildFrom
object PrefixMap {
def empty[T] = new PrefixMap[T]
def apply[T](kvs: (String, T)*): PrefixMap[T] = {
val m: PrefixMap[T] = empty
for(kv <- kvs) m += kv
m
}
def newBuilder[T]: Builder[(String, T), PrefixMap[T]] = {
new mutable.MapBuilder[String, T, PrefixMap[T]](empty)
}
implicit def canBuildFrom[T]: CanBuildFrom[PrefixMap[_], (String, T), PrefixMap[T]] = {
new CanBuildFrom[PrefixMap[_], (String, T), PrefixMap[T]] {
def apply(from: PrefixMap[_]) = newBuilder[T]
def apply() = newBuilder[T]
}
}
}
}
I don't understand this line:
def apply(from: PrefixMap[_]) = newBuilder[T]
What's point in receiving a PrefixMap and returning a empty PrefixMap?
Read little bit more official docs
If in short: CBF can return builder with knowledge of properties of whole collection.
For example it could preinitialize some buffer of needed size to collect entries.
Or even reuse some parts of collection of known type and structure.
But by default in many case it would just collect element by element to empty collection. That's happening in your case.

Advantages of using this.type in Scala?

Here is an example from the stairway book:
object Example1 {
import collection._
class PrefixMap[T]
extends mutable.Map[String, T]
with mutable.MapLike[String, T, PrefixMap[T]] {
var suffixes: immutable.Map[Char, PrefixMap[T]] = Map.empty
var value: Option[T] = None
def get(s: String): Option[T] = {
// base case, you are at the root
if (s.isEmpty) value
// recursive
else suffixes get (s(0)) flatMap (_.get(s substring 1))
}
def withPrefix(s: String): PrefixMap[T] = {
if (s.isEmpty) this
else {
val leading = s(0)
suffixes get leading match {
case None => {
// key does not exist, create it
suffixes = suffixes + (leading -> empty)
}
case _ =>
}
// recursion
suffixes(leading) withPrefix (s substring 1)
}
}
override def update(s: String, elem: T) = {
withPrefix(s).value = Some(elem)
}
override def remove(key: String): Option[T] = {
if (key.isEmpty) {
// base case. you are at the root
val prev = value
value = None
prev
} else {
// recursive
suffixes get key(0) flatMap (_.remove(key substring 1))
}
}
def iterator: Iterator[(String, T)] = {
(for (v <- value.iterator) yield ("", v)) ++
(for ((chr, m) <- suffixes.iterator; (s, v) <- m.iterator) yield (chr +: s, v))
}
def +=(kv: (String, T)): this.type = {
update(kv._1, kv._2)
this
}
def -=(key: String): this.type = {
remove(key)
this
}
override def empty = new PrefixMap[T]
}
}
Note that for the methods += and -=, the return types are this.type. Can I use PrefixMap[T] here? If yes, what does this.type has to offer?
Can I use PrefixMap[T] here?
Yes.
If yes, what does this.type has to offer?
For example, imagine you also have another class PrefixMap2[T] extending PrefixMap. Then with this.type, += and -= called on a PrefixMap2 will return itself (and therefore, a PrefixMap2); with PrefixMap return type, the compiler will only know they return a PrefixMap.