Type parameter issue in Scala with generic function - scala

I'm trying to come up with a generic function (toBitSet) using type parameter T.
def toBitSet[T:Integral](x:T, valueBitwidth:Int, filterBitwidth:Int, bigEndian:Boolean = true, shift:Int = 0) = {
BitSet((for (i <- 0 to (valueBitwidth - 1) if (((x & 0xFF) >> i) & 1) == 1) yield (i + shift)): _*)
}
byteToBitSet and shortToBitSet functions are specializaton of the generic function.
def byteToBitSet(x:Byte, filterBitwidth:Int, bigEndian:Boolean = true, shift:Int = 0) = {
toBitSet[Byte](x = x, valueBitwidth = 8, filterBitwidth = filterBitwidth, bigEndian = bigEndian, shift = shift)
}
def shortToBitSet(x:Short, filterBitwidth:Int, bigEndian:Boolean = true, shift:Int = 0) = {
toBitSet[Short](x = x, valueBitwidth = 16, filterBitwidth = filterBitwidth, bigEndian = bigEndian, shift = shift)
}
However, Scala doesn't understand the operators (>>, &, ==, +) on type T to show an error message. I specified that T is Integral type, but it doesn't work.
How to solve this issue?

The type signature
def func[T: Integral](arg: T) = {}
is actually a syntactic shorthand for:
def func[T](arg: T)(implicit ev: Integral[T]) = {} ("ev" is often chosen as the name for this "evidence" argument.)
The Integral trait outlines what operations you then use on elements of type T. Example: addition is ev.plus(t1, t2)
If you import Integral.Implicits._ then you can use the more natural infix notation: t1 + t2
Unfortunately, the Integral trait doesn't include bit-wise operations like & and >>.
If you can modify your algorithm to use only those available ops you'll get the function you're after.

Related

Using the kronecker product on complex matrices with scalaNLP breeze

I had a piece of code:
def this(vectors: List[DenseVector[Double]]) {
this(vectors.length)
var resultVector = vectors.head
for (vector <- vectors) {
resultVector = kron(resultVector.toDenseMatrix, vector.toDenseMatrix).toDenseVector
}
_vector = resultVector
}
It worked just the way I wanted it to work. The problem is that I needed complex values in stead of doubles. After importing breeze.math.Complex, I changed the code to:
def this(vectors: List[DenseVector[Complex]]) {
this(vectors.length)
var resultVector = vectors.head
for (vector <- vectors) {
resultVector = kron(resultVector.toDenseMatrix, vector.toDenseMatrix).toDenseVector
}
_vector = resultVector
}
This however results into the errors:
Error:(42, 26) could not find implicit value for parameter impl: breeze.linalg.kron.Impl2[breeze.linalg.DenseMatrix[breeze.math.Complex],breeze.linalg.DenseMatrix[breeze.math.Complex],VR]
resultVector = kron(resultVector.toDenseMatrix, vector.toDenseMatrix).toDenseVector
^
Error:(42, 26) not enough arguments for method apply: (implicit impl: breeze.linalg.kron.Impl2[breeze.linalg.DenseMatrix[breeze.math.Complex],breeze.linalg.DenseMatrix[breeze.math.Complex],VR])VR in trait UFunc.
Unspecified value parameter impl.
resultVector = kron(resultVector.toDenseMatrix, vector.toDenseMatrix).toDenseVector
^
Is this a bug or am I forgetting to do something?
I found the problem in the following way:
I first rewrote the function to use less matrix conversions
As there was a problem with the implicit impl variable of kron, I also rewrote the function call to explicitly state which variable to use to use
.
def this(vectors: List[DenseVector[Complex]]) {
this(vectors.length)
var resultMatrix = vectors.head.toDenseMatrix
for (i <- 1 until vectors.length) {
resultMatrix = kron(resultMatrix, vectors(i).toDenseMatrix)(kron.kronDM_M[Complex, Complex, DenseMatrix[Complex], Complex])
}
_vector = resultMatrix.toDenseVector
}
This showed me that there was no ScalarMulOp for V2, M, DenseMatrix[RV] where M is a Matrix[V1], V1 and V2 are the input types and RV is the output type of the ScalarMulOp
Digging through the source code of breeze I found in DenseMatrixOps that there only was an implicit ScalarMulOp for the above types if V1, V2 and RV are of type Int, Long, Float and Double. By copying the function and making it specific for Complex numbers, I was able to get the kronecker product to work. Now I could also remove the explicit use of (kron.kronDM_M[Complex, Complex, DenseMatrix[Complex], Complex]). The ScalarMulOp function in question is:
implicit def s_dm_op_Complex_OpMulScalar(implicit op: OpMulScalar.Impl2[Complex, Complex, Complex]):
OpMulScalar.Impl2[Complex, DenseMatrix[Complex], DenseMatrix[Complex]] =
new OpMulScalar.Impl2[Complex, DenseMatrix[Complex], DenseMatrix[Complex]] {
def apply(b: Complex, a: DenseMatrix[Complex]): DenseMatrix[Complex] = {
val res: DenseMatrix[Complex] = DenseMatrix.zeros[Complex](a.rows, a.cols)
val resd: Array[Complex] = res.data
val ad: Array[Complex] = a.data
var c = 0
var off = 0
while (c < a.cols) {
var r = 0
while (r < a.rows) {
resd(off) = op(b, ad(a.linearIndex(r, c)))
r += 1
off += 1
}
c += 1
}
res
}
implicitly[BinaryRegistry[Complex, Matrix[Complex], OpMulScalar.type, Matrix[Complex]]].register(this)
}

Scala function with a recursive function parameter

I am curious if can implement a Scala function similar to this Javascript function. Obviously, I can do it easily with an inner function.
Knowing that Scala has to declare the parameter type and arity upfront, I just wonder if there is anything I could use to implement this JS function. Thanks.
function factorial(x) {
if (x < 0) throw Error("Cannot calculate factorial of a negative number");
return (function(f) {
return f(f, x, 1);
})(function(f, i, fact) {
return i === 0 ? fact : f(f, i-1, i*fact);
});
}
If I have understood your question correctly, indeed you can do this and the best known approach is to use what's called a Y-combinator. In short a Y-combinator takes a function as a parameter and keeps applying it. The Y-combinator has no knowledge of the parameter types involved
Copying the example Y-combinator right from rosetta code:
def Y[A,B](f: (A=>B)=>(A=>B)) = {
case class W(wf: W=>A=>B) {
def apply(w: W) = wf(w)
}
val g: W=>A=>B = w => f(w(w))(_)
g(W(g))
}
defines your combinator. You can then pass it your recursive function
val fac = Y[Int, Int](f => i => if (i <= 0) 1 else f(i - 1) * i)
fac: Int => Int = <function1>
And then give that something to evaluate
scala> fac(6)
res0: Int = 720

Scala comparing type:Ordering

I have a sorting function like this:
def sort[A:Ordering](vals: Array[A]):Array[A] = {
for (i <- 1 until vals.length) {
val temp = vals(i)
var j = i
while (j > 0 && temp < vals(j-1) ){
vals(j) = vals(j-1)
j -= 1
}
vals(j) = temp;
}
vals
}
And its supposed to get an array of type A(which is either Int or String, but the code doesn't know that) as a parameter and sort it and then return it.
Now eclipse tells me that:
"value < is not a member of type parameter A"
at line 5. I donĀ“t understand why can't it compare those values, I've tried A:Comparable, A:Ordered and A:every-word-that-could-possibly-work. Nothing works.
Any help is appreciated!
Thanks!
[A:Ordering] on a function sort means that there should exist such implicit value (to be completely honest it may not be implicit, but in this case you'll have to pass it by manually), that has type Ordering[A] at the point of sort call, and this implicit value will be added in separate argument list of the function.
This is how typeclasses supported in Scala.
This won't magically add < to A, as there is no type bound on A and compiller can know no more that A is a subtype of Any.
Anyway, to use ordering in body of your sort you can obtain it using:
implicitly[Ordering[A]]
... and then use it. This works because, again implicit value of type Ordering[A] were added behind the scenes in extra argument list of sort.
Here is a code snippet that should give you an idea on how to use it in your code:
scala> def lt[T : Ordering](a: T, b: T) = { implicitly[Ordering[T]].lt(a, b) }
lt: [T](a: T, b: T)(implicit evidence$1: Ordering[T])Boolean
scala> lt(1, 1)
res9: Boolean = false
scala> lt(1, 2)
res10: Boolean = true

Type mismatch for generic Integral in Scala

I am trying to code a decoder for Base64 Variable Length Quanties in Scala.
(Base64 VLQ encodes a sequences of signed integers. The encoding has no restrictions on the range of integers encoded.)
For my current use case, I kow that Seq[Int] will suffice. Of course, I'd like to make it so I can decode to Seq[Long], or Seq[BigInteger], or even something like Seq[Short].
The algorithm is exactly the same, just with different types.
Generics to the rescue! (Or so I thought.)
object Base64Vlq {
val continuationMask = (1 << 5).toByte
val signMask = 1.toByte
def decode[T <: Integral[T]](bytes: Seq[Byte]): Seq[T] = {
val result = scala.collection.mutable.ListBuffer[T]()
bytes.foldLeft((0, 0)) { (arg, byte) =>
val (value, n) = arg
if((byte & continuationMask) == 0) {
val newValue = value + (byte / 2 & ~continuationMask) << 5 * n
result += (if((byte & signMask) == 0) { newValue } else { -newValue })
(0, 0)
} else {
(value + (byte & ~continuationMask).toInt << 5 * n, n + 1)
}
}
result
}
}
This has a compile error:
error: type mismatch;
found : newValue.type (with underlying type Int)
required: T
result += (if((byte & signMask) == 0) { newValue } else { -newValue })
I can see the problem: 0, value, and newValue are all of type Int.
What can I do to fix this?
FYI, this is how I would do the same thing in C++, with only a couple more lines of code.
#include <vector>
template<typename T>
std::vector<T> decode(std::vector<char> bytes) {
char continuationMask = 1 << 5;
char signMask = 1;
vector<T> result;
int n(0);
T value(0);
for(auto it = bytes.begin(); it != bytes.end(); it++) {
if(*it & continuationMask) {
value += (*it & ~continuationMask) << 5 * n;
n++;
} else {
value += (*it / 2 & ~continuationMask) << 5 * n;
result.push_back(*it & signMask ? -value : value);
value = 0;
n = 0;
}
}
return result;
}
P.S. As a side note, if anyone knows of a Java/Scala based Base64 VLQ implementation in public Maven/Ivy repos, even if it's not generic, I'd appreciate knowing it.
The bound T <: Integral[T] says T must be a subtype of Integral[T], which is wrong; you need a context bound T: Integral instead or (better for this case) an implicit parameter (actually, a context bound compiles to an implicit parameter, the only difference is that you can't give it a name).
Something like this (not tested, just checked that it compiles):
object Base64Vlq {
val continuationMask = (1 << 5).toByte
val signMask = 1.toByte
def decode[T](bytes: Seq[Byte])(implicit ev: Integral[T]): Seq[T] = {
val result = scala.collection.mutable.ListBuffer[T]()
val tZero = ev.zero
bytes.foldLeft((tZero, 0)) { (arg, byte) =>
val (value, n) = arg
if((byte & continuationMask) == 0) {
val newValue = ev.plus(value, ev.fromInt((byte / 2 & ~continuationMask) << 5 * n))
result += (if((byte & signMask) == 0) { newValue } else { ev.negate(newValue) })
(tZero, 0)
} else {
(ev.plus(value, ev.fromInt((byte & ~continuationMask).toInt << 5 * n)), n + 1)
}
}
result
}
}
To use, you'll have to say what type you want to get out:
EDIT: I didn't see that in your C++ code n was T and assumed it was an Int.
Answers to the comment:
That's just how types like Integral work: they are Scala's version of type classes. If you want to introduce new operations on existing types, you obviously can't add new supertypes to them, so instead implicit instances for Integral[Int], Integral[BigInt] and so on are created.
The compiler doesn't know what type to use for T and you need to tell it: e.g. Base64Vlq.decode[Int](Seq[Byte]()) or Base64Vlq.decode[BigInt](Seq[Byte]()).
This doesn't solve your issue, but hopefully it helps you to write a generic solution. Take a look at operations provided by Integral and IntegralOps. The problem is with bit operations. If you choose to go this way, you would have to rewrite them using operations supported by Integral and IntegralOps. Good luck.
object Base64Vlq {
val continuationMask = (1 << 5).toByte
val signMask = 1.toByte
def decode[T](bytes: Seq[Byte])(implicit integral: Integral[T]): Seq[T] = {
import integral._
val result = scala.collection.mutable.ListBuffer[T]()
bytes.foldLeft((integral.zero, integral.zero)) { (arg, byte) =>
val (value, n) = arg
if((byte & continuationMask) == integral.zero) {
// Just a meaningless example calculation:
result += integral.fromInt(2) + (value * n)
(integral.zero, integral.zero)
} else {
// Just a meaningless example calculation:
(value + integral.fromInt(3) * n, n + integral.fromInt(1))
}
}
result
}
}

How to add 'Array[Ordered[Any]]' as a method parameter

Below is an implementation of Selection sort written in Scala.
The line ss.sort(arr) causes this error :
type mismatch; found : Array[String] required: Array[Ordered[Any]]
Since the type Ordered is inherited by StringOps should this type not be inferred ?
How can I add the array of Strings to sort() method ?
Here is the complete code :
object SelectionSortTest {
def main(args: Array[String]){
val arr = Array("Hello","World")
val ss = new SelectionSort()
ss.sort(arr)
}
}
class SelectionSort {
def sort(a : Array[Ordered[Any]]) = {
var N = a.length
for (i <- 0 until N) {
var min = i
for(j <- i + 1 until N){
if( less(a(j) , a(min))){
min = j
}
exchange(a , i , min)
}
}
}
def less(v : Ordered[Any] , w : Ordered[Any]) = {
v.compareTo(w) < 0
}
def exchange(a : Array[Ordered[Any]] , i : Integer , j : Integer) = {
var swap : Ordered[Any] = a(i)
a(i) = a(j)
a(j) = swap
}
}
Array is invariant. You cannot use an Array[A] as an Array[B] even if A is subtype of B. See here why: Why are Arrays invariant, but Lists covariant?
Neither is Ordered, so your implementation of less will not work either.
You should make your implementation generic the following way:
object SelectionSortTest {
def main(args: Array[String]){
val arr = Array("Hello","World")
val ss = new SelectionSort()
ss.sort(arr)
}
}
class SelectionSort {
def sort[T <% Ordered[T]](a : Array[T]) = {
var N = a.length
for (i <- 0 until N) {
var min = i
for(j <- i + 1 until N){
if(a(j) < a(min)){ // call less directly on Ordered[T]
min = j
}
exchange(a , i , min)
}
}
}
def exchange[T](a : Array[T] , i : Integer , j : Integer) = {
var swap = a(i)
a(i) = a(j)
a(j) = swap
}
}
The somewhat bizarre statement T <% Ordered[T] means "any type T that can be implicitly converted to Ordered[T]". This ensures that you can still use the less-than operator.
See this for details:
What are Scala context and view bounds?
The answer by #gzm0 (with some very nice links) suggests Ordered. I'm going to complement with an answer covering Ordering, which provides equivalent functionality without imposing on your classes as much.
Let's adjust the sort method to accept an array of type 'T' for which an Ordering implicit instance is defined.
def sort[T : Ordering](a: Array[T]) = {
val ord = implicitly[Ordering[T]]
import ord._ // now comparison operations such as '<' are available for 'T'
// ...
if (a(j) < a(min))
// ...
}
The [T : Ordering] and implicitly[Ordering[T]] combo is equivalent to an implicit parameter of type Ordering[T]:
def sort[T](a: Array[T])(implicit ord: Ordering[T]) = {
import ord._
// ...
}
Why is this useful?
Imagine you are provided with a case class Account(balance: Int) by some third party. You can now add an Ordering for it like so:
// somewhere in scope
implicit val accountOrdering = new Ordering[Account] {
def compare(x: Account, y: Account) = x.balance - y.balance
}
// or, more simply
implicit val accountOrdering: Ordering[Account] = Ordering by (_.balance)
As long as that instance is in scope, you should be able to use sort(accounts).
If you want to use some different ordering, you can also provide it explicitly, like so: sort(accounts)(otherOrdering).
Note that this isn't very different from providing an implicit conversion to Ordering (at least not within the context of this question).
Even though, when coding Scala, I'm used to prefer functional programming style (via combinators or recursion) over imperative style (via variables and iterations), THIS TIME, for this specific problem, old school imperative nested loops result in simpler and performant code.
I don't think falling back to imperative style is a mistake for certain classes of problems, such as sorting algorithms which usually transform the input buffer (more like a procedure) rather than resulting to a new sorted collection.
Here it is my solution:
package bitspoke.algo
import scala.math.Ordered
import scala.collection.mutable.Buffer
abstract class Sorter[T <% Ordered[T]] {
// algorithm provided by subclasses
def sort(buffer : Buffer[T]) : Unit
// check if the buffer is sorted
def sorted(buffer : Buffer[T]) = buffer.isEmpty || buffer.view.zip(buffer.tail).forall { t => t._2 > t._1 }
// swap elements in buffer
def swap(buffer : Buffer[T], i:Int, j:Int) {
val temp = buffer(i)
buffer(i) = buffer(j)
buffer(j) = temp
}
}
class SelectionSorter[T <% Ordered[T]] extends Sorter[T] {
def sort(buffer : Buffer[T]) : Unit = {
for (i <- 0 until buffer.length) {
var min = i
for (j <- i until buffer.length) {
if (buffer(j) < buffer(min))
min = j
}
swap(buffer, i, min)
}
}
}
As you can see, to achieve parametric polymorphism, rather than using java.lang.Comparable, I preferred scala.math.Ordered and Scala View Bounds rather than Upper Bounds. That's certainly works thanks to Scala Implicit Conversions of primitive types to Rich Wrappers.
You can write a client program as follows:
import bitspoke.algo._
import scala.collection.mutable._
val sorter = new SelectionSorter[Int]
val buffer = ArrayBuffer(3, 0, 4, 2, 1)
sorter.sort(buffer)
assert(sorter.sorted(buffer))