Scala bitwise-like method argument - scala

Let's say there is a generic method declaration that performs a set of operations based upon a designated mode that would look something like this:
def doSomethingSmart(mode: OpMode, someGoodyList: List[Any]): Boolean = { /* do foo */ }
Where OpMode is a type/enumeration consisting of:
Read
Create
Delete
Modify
Whatever
Putting the two together would obviously yield a single-mode, reusable, code block.
Now, the type/enumeration part would probably look something like this:
object OpMode extends Enumeration {
type OpMode = Value
val Read, Write, Create, Modify, Delete, Whatever = Value
}
But let's say you wanted to expand the scope of doSomethingSmart() to span what is typically done using bitwise operators, for example: Create & Modify & Whatever. Is there a "scala-way" of restricting the bit-masked argument to that limited data-set (ie, the enumeration/type). Maybe something along these lines:
def doSomethingSmarter(more: T < [BitwiseSelectionOf[OpMode]], ...
Or, is it best to simply drop back to binary-indexed value assignments - in which cases there is no "type" checking per se?
TIA.
EDIT: I guess another possibility would be to change the OpMode to be a List and then just run a series of "contains" operations.
EDIT 2: In particular, I was looking for an efficient mechanism that provides an inline construct when making a call to doSomethingSmarter()

Enumeration defines an inner type called ValueSet which gives you at least some of the functionality you are looking for. The methods on it are still Set-like (you would add a new mode using +, and check for a mode using contains), but it may serve your purposes.
EDIT: had some fun fiddling around and came up with this:
import scala.collection.BitSet
object OpMode extends Enumeration {
protected case class Val(name: String, val mask: Int) extends super.Val(nextId, name)
type OpMode = Val
val Read = Val("Read", 1)
val Write = Val("Write", 2)
val Create = Val("Create", 4)
val Modify = Val("Modify", 8)
val Delete = Val("Delete", 16)
val Whatever = Val("Whatever", 32)
case class FlagSet(bits: BitSet) {
def isSet(mode: OpMode) = bits.contains(mode.mask)
def +(mode: OpMode) = new FlagSet(bits + mode.mask)
def -(mode: OpMode) = new FlagSet(bits - mode.mask)
def &(other: FlagSet) = new FlagSet(bits & other.bits)
def &~(other: FlagSet) = new FlagSet(bits &~ other.bits)
def ^(other: FlagSet) = new FlagSet(bits ^ other.bits)
def |(other: FlagSet) = new FlagSet(bits | other.bits)
def size = bits.size
// etc.
}
object FlagSet {
def apply(flags: OpMode*): FlagSet = apply(BitSet(flags.map(_.mask):_*))
def apply(modes: ValueSet): FlagSet = apply(BitSet(modes.toSeq.map{ case m: OpMode => m.mask }:_*))
}
}
def doSomethingSmarter(modes: OpMode.FlagSet, someGoodyList: List[Any]) = modes.size
val flags = OpMode.FlagSet(OpMode.Read, OpMode.Write)
doSomethingSmarter(flags, Nil)
val modes = OpMode.ValueSet(OpMode.Read, OpMode.Write)
doSomethingSmarter(OpMode.FlagSet(modes), Nil)
Basically, I extended the Enumeration.Val type to add a suitable bit mask for each mode, and added an inner class FlagSet to interoperate between OpModes and an under-the-covers BitSet. Changing doSomethingSmarter to take in such a FlagSet enables usage that should be closer to what you are hoping for.
The above can probably be improved upon, but working with Enumeration can be tricky. As an alternative, you might find it preferable to work with a sealed trait and case classes/objects extending it - this can often give semantics closer to what is possible with Java's enum types.

Related

How to override some generators for ScalaCheck to force to (automatically) generate refined types? Non empty lists only, for example

I have a quite big structure of case classes and somewhere deep inside this structure I have fields which I want to refine, for example, make lists non-empty. Is it possible to tell ScalaCheck to make those lists non-empty using automatic derivation from scalacheck-magnolia project (without providing each field specifically)?
Example:
import com.mrdziuban.ScalacheckMagnolia.deriveArbitrary
import org.scalacheck.Arbitrary
import org.scalacheck.Gen
case class A(b: B, c: C)
case class B(list: List[Long])
case class C(list: List[Long])
// I've tried:
def genNEL[T: Gen]: Gen[List[T]] = Gen.nonEmptyListOf(implicitly[Gen[T]])
implicit val deriveNEL = Arbitrary(genNEL)
implicit val deriveA = implicitly[Arbitrary[A]](deriveArbitrary)
But it's didn't worked out.
I'm not sure how to be generic, since I'm not familiar with getting automatic derivation for Arbitrary with scalacheck-magnolia. It seems like scalacheck-magnolia is good for deriving an Arbitrary for case classes, but maybe not for containers (lists, vectors, arrays, etc.).
If you want to just use plain ScalaCheck, you could just define the implicit Arbitrary for A yourself. Doing it by hand is some extra boilerplate, but it has the benefit that you have more control if you want to use different generators for different parts of your data structure.
Here's an example where an Arbitrary list of longs is non-empty by default, but is empty for B.
implicit val listOfLong =
Arbitrary(Gen.nonEmptyListOf(Arbitrary.arbitrary[Long]))
implicit val arbC = Arbitrary {
Gen.resultOf(C)
}
implicit val arbB = Arbitrary {
implicit val listOfLong =
Arbitrary(Gen.listOf(Arbitrary.arbitrary[Long]))
Gen.resultOf(B)
}
implicit val arbA = Arbitrary {
Gen.resultOf(A)
}
property("arbitrary[A]") = {
Prop.forAll { a: A =>
a.b.list.size >= 0 && a.c.list.size > 0
}
}

Is it possible to specify that a type will have a certain parameters in its constructor? Scala

So I have a class that suppose to use generic type, but that type should be with certain characteristics
It needs to have defined method calculate
It needs to have constructor that accepts Seq[Double]
At the moment I have a trait
trait HasCalculate {def calculate(): Double}
And I use it this way:
val pars = Seq(1.0, 2.0)
val calc = new Calc1(pars) with HasCalculate
val res = calc.calculate
When I want to use another calculator I put Calc2 instead Calc1 in the code of the class. But I would like to do it generic way, something like:
class MyClass[T]{
val pars = Seq(1.0, 2.0)
val calc = new T(pars) with HasCalculate
val res = calc.calculate
}
But how to define that T has constructor that accepts Seq[Double]?
What you're describing doesn't sound like it's possible in Scala (which doesn't really have facilities for abstracting over constructors), and without knowing your larger goals more specifically it's hard to offer good advice, but the following is a Scala-idiomatic solution that provides the kind of usage it looks like you want for MyClass and that is specifically designed to let you use generic types while constraining those types to have certain operations.
The first step is to write a type class that captures the operations you need:
trait Calculable[A] {
def create(values: Seq[Double]): A
def calculate(a: A): Double
}
You can think of instances of this type as "evidence" that you can perform these operations on some A.
Next you'd write your MyClass like this:
class MyClass[T: Calculable] {
private val instance = implicitly[Calculable[T]]
val pars = Seq(1.0, 2.0)
val calc: T = instance.create(pars)
val res: Double = instance.calculate(calc)
}
The T: Calculable part is a "context bound", which specifies that there must be implicit evidence that T has a Calculable instance. It's a constraint that says "T can be any type, as long as we know how to do the Calculable operations on it".
Now you could write a particular class that could be used as T like this:
class MyCalculation(vs: Seq[Double]) {
def calculate(): Double = vs.sum
}
object MyCalculation {
implicit val calculableInstance: Calculable[MyCalculation] =
new Calculable[MyCalculation] {
def create(values: Seq[Double]): MyCalculation = new MyCalculation(values)
def calculate(a: MyCalculation): Double = a.calculate()
}
}
And you get the usage you want:
scala> val myClass = new MyClass[MyCalculation]
myClass: MyClass[MyCalculation] = MyClass#646bf8a6
scala> myClass.res
res0: Double = 3.0
If you control the definition of MyCalculation, the most convenient place to define its implicit Calculable[MyCalculation] is the MyCalculation companion object, but one of the advantages of the type class approach is that it separates the definition of operations on a type from the definition of the type, and these instances can be defined separately.
I came up with an answer myself I would like to share...
So instead MyClass has type parameter it could have a function as parameter, something like this:
class MyClass(f:(Seq[Double])=>HasCalculate){
val pars = Seq(1.0, 2.0)
val calc = f(pars)
val res = calc.calculate
}
And then to provide an anonymous function with the constructor in its body:
val myClass = new MyClass((s:Seq[Double])=>new Calc1(s) with HasCalculate)
Of course this looks ugly but in my case it appears to be more practical than Travis's solution, since I have lots of calculators and I don't intend to create that factory object for each of them or each time I want to run a calculator through MyClass. I just copy this line of code and replace Calc1 with Calc99...
So if you have few calculators and lots of calls to MyClass, definitely Trevis's solution is better, otherwise this might be useful...

Generic synchronisation design

We are building some sync functionality using two-way json requests and this algorithm. All good and we have it running in prototype mode. Now I am trying to genericise the code, as we will be synching for several tables in the app. It would be cool to be able to define a class as "extends Synchable" and get the additional attributes and sync processing methods with a few specialisations/overrides. I have got this far:
abstract class Synchable [T<:Synchable[T]] (val ruid: String, val lastSyncTime: String, val isDeleted:Int) {
def contentEquals(Target: T): Boolean
def updateWith(target: T)
def insert
def selectSince(clientLastSyncTime: String): List[T]
def findByRuid(ruid: String): Option[T]
implicit val validator: Reads[T]
def process(clientLastSyncTime: String, updateRowList: List[JsObject]) = {
for (syncRow <- updateRowList) {
val validatedSyncRow = syncRow.validate[Synchable]
validatedSyncRow.fold(
valid = { result => // valid row
findByRuid(result.ruid) match { //- do we know about it?
case Some(knownRow) => knownRow.updateWith(result)
case None => result.insert
}
}... invalid, etc
I am new to Scala and know I am probably missing things - WIP!
Any pointers or suggestions on this approach would be much appreciated.
Some quick ones:
Those _ parameters you pass in and then immediately assign to vals: why not do it in one hit? e.g.
abstract class Synchable( val ruid: String = "", val lastSyncTime: String = "", val isDeleted: Int = 0) {
which saves you a line and is clearer in intent as well I think.
I'm not sure about your defaulting of Strings to "" - unless there's a good reason (and there often is), I think using something like ruid:Option[String] = None is more explicit and lets you do all sorts of nice monad-y things like fold, map, flatMap etc.
Looking pretty cool otherwise - the only other thing you might want to do is strengthen the typing with a bit of this.type magic so you'll prevent incorrect usage at compile-time. With your current abstract class, nothing prevents me from doing:
class SynchableCat extends Synchable { ... }
class SynchableDog extends Synchable { ... }
val cat = new SynchableCat
val dog = new SynchableDog
cat.updateWith(dog) // This won't end well
But if you just change your abstract method signatures to things like this:
def updateWith(target: this.type)
Then the change ripples down through the subclasses, narrowing down the types, and the compiler will omit a (relatively clear) error if I try the above update operation.

Does Scala have record update syntax for making modified clones of immutable data structures?

In Mercury I can use:
A = B^some_field := SomeValue
to bind A to a copy of B, except that some_field is SomeValue instead of whatever it was in B. I believe the Haskell equivalent is something like:
a = b { some_field = some_value }
Does Scala have something like this for "modifying" immutable values. The alternative seems to be to have a constructor that directly sets every field in the instance, which isn't always ideal (if there are invarients the constructor should be maintaining). Plus it would be really clunky and much more fragile if I had to explicitly pass every other value in the instance I want to have a modified copy of.
I couldn't find anything about this by googling, or in a brief survey of the language reference manual or "Scala By Example" (which I have read start-to-finish, but haven't absorbed all of yet, so it may well be in there).
I can see that this feature could have some weird interactions with Java-style access protection and subclasses though...
If you define your class as a case class, a convenient copy method is generated, and calling it you can specify with named parameters new values for certain fields.
scala> case class Sample(str: String, int: Int)
defined class Sample
scala> val s = Sample("text", 42)
s: Sample = Sample(text,42)
scala> val s2 = s.copy(str = "newText")
s2: Sample = Sample(newText,42)
It even works with polymorphic case classes:
scala> case class Sample[T](t: T, int: Int)
defined class Sample
scala> val s = Sample("text", 42)
s: Sample[java.lang.String] = Sample(text,42)
scala> val s2 = s.copy(t = List(1,2,3), 42)
s2: Sample[List[Int]] = Sample(List(1, 2, 3),42)
Note that s2 has a different type than s.
You can use case classes for this, but you don't have to. Case classes are nothing magical - the modifier case just saves you a lot of typing.
The copy method is realized by the use of named and default parameters. The names are the same as the fields and the defaults are the current values of the fields. Here's an example:
class ClassWithCopy(val field1:String, val field2:Int) {
def copy(field1:String = this.field1, field2:Int = this.field2) = {
new ClassWithCopy(field1,field2);
}
}
You can use this just like the copy method on case classes. Named and default parameters are a very useful feature, and not only for copy methods.
If the object you're planning on modifying is a case class then you can use the autogenerated copy method:
scala> val user = User(2, "Sen")
user: User = User(2,Sen)
scala> val corrected = user.copy(name = "Sean")
corrected: User = User(2,Sean)

Extending Scala collections: One based Array index exercise

As an exercise, I'd like to extend the Scala Array collection to my own OneBasedArray (does what you'd expect, indexing starts from 1). Since this is an immutable collection, I'd like to have it return the correct type when calling filter/map etc.
I've read the resources here, here and here, but am struggling to understand how to translate this to Arrays (or collections other than the ones in the examples). Am I on the right track with this sort of structure?
class OneBasedArray[T]
extends Array[T]
with GenericTraversableTemplate[T, OneBasedArray]
with ArrayLike[T, OneBasedArray]
Are there any further resources that help explain extending collections?
For a in depth overview of new collections API: The Scala 2.8 Collections API
For a nice view of the relation between main classes and traits this
By the way I don't think Array is a collection in Scala.
Here is an example of pimping iterables with a method that always returns the expected runtime type of the iterable it operates on:
import scala.collection.generic.CanBuildFrom
trait MapOrElse[A] {
val underlying: Iterable[A]
def mapOrElse[B, To]
(m: A => Unit)
(pf: PartialFunction[A,B])
(implicit cbf: CanBuildFrom[Iterable[A], B, To])
: To = {
var builder = cbf(underlying.repr)
for (a <- underlying) if (pf.isDefinedAt(a)) builder += pf(a) else m(a)
builder.result
}
}
implicit def toMapOrElse[A](it: Iterable[A]): MapOrElse[A] =
new MapOrElse[A] {val underlying = it}
The new function mapOrElse is similar to the collect function but it allows you to pass a method m: A => Unit in addition to a partial function pf that is invoked whenever pf is undefined. m can for example be a logging method.
An Array is not a Traversable -- trying to work with that as a base class will cause all sorts of problems. Also, it is not immutable either, which makes it completely unsuited to what you want. Finally, Array is an implementation -- try to inherit from traits or abstract classes.
Array isn't a typical Scala collection... It's simply a Java array that's pimped to look like a collection by way of implicit conversions.
Given the messed-up variance of Java Arrays, you really don't want to be using them without an extremely compelling reason, as they're a source of lurking bugs.
(see here: http://www.infoq.com/presentations/Java-Puzzlers)
Creaking a 1-based collection like this isn't really a good idea either, as you have no way of knowing how many other collection methods rely on the assumption that sequences are 0-based. So to do it safely (if you really must) you'll want add a new method that leaves the default one unchanged:
class OneBasedLookup[T](seq:Seq) {
def atIdx(i:Int) = seq(i-1)
}
implicit def seqHasOneBasedLookup(seq:Seq) = new OneBasedLookup(seq)
// now use `atIdx` on any sequence.
Even safer still, you can create a Map[Int,T], with the indices being one-based
(Iterator.from(1) zip seq).toMap
This is arguably the most "correct" solution, although it will also carry the highest performance cost.
Not an array, but here's a one-based immutable IndexedSeq implementation that I recently put together. I followed the example given here where they implement an RNA class. Between that example, the ScalaDocs, and lots of "helpful" compiler errors, I managed to get it set up correctly. The fact that OneBasedSeq is genericized made it a little more complex than the RNA example. Also, in addition to the traits extended and methods overridden in the example, I had to extend IterableLike and override the iterator method, because various methods call that method behind the scenes, and the default iterator is zero-based.
Please pardon any stylistic or idiomadic oddities; I've been programming in Scala for less than 2 months.
import collection.{IndexedSeqLike, IterableLike}
import collection.generic.CanBuildFrom
import collection.mutable.{Builder, ArrayBuffer}
// OneBasedSeq class
final class OneBasedSeq[T] private (s: Seq[T]) extends IndexedSeq[T]
with IterableLike[T, OneBasedSeq[T]] with IndexedSeqLike[T, OneBasedSeq[T]]
{
private val innerSeq = s.toIndexedSeq
def apply(idx: Int): T = innerSeq(idx - 1)
def length: Int = innerSeq.length
override def iterator: Iterator[T] = new OneBasedSeqIterator(this)
override def newBuilder: Builder[T, OneBasedSeq[T]] = OneBasedSeq.newBuilder
override def toString = "OneBasedSeq" + super.toString
}
// OneBasedSeq companion object
object OneBasedSeq {
private def fromSeq[T](s: Seq[T]) = new OneBasedSeq(s)
def apply[T](vals: T*) = fromSeq(IndexedSeq(vals: _*))
def newBuilder[T]: Builder[T, OneBasedSeq[T]] =
new ArrayBuffer[T].mapResult(OneBasedSeq.fromSeq)
implicit def canBuildFrom[T, U]: CanBuildFrom[OneBasedSeq[T], U, OneBasedSeq[U]] =
new CanBuildFrom[OneBasedSeq[T], U, OneBasedSeq[U]] {
def apply() = newBuilder
def apply(from: OneBasedSeq[T]): Builder[U, OneBasedSeq[U]] = newBuilder[U]
}
}
// Iterator class for OneBasedSeq
class OneBasedSeqIterator[T](private val obs: OneBasedSeq[T]) extends Iterator[T]
{
private var index = 1
def hasNext: Boolean = index <= obs.length
def next: T = {
val ret = obs(index)
index += 1
ret
}
}