Beginner for loop in Scala: How do I declare a generic element? - scala

I'm new to Scala and am having trouble with a simple generic for-loop declaration, where one instance of my class, FinSet[T] is "unionized" with my another instance of FinSet[T], other. Here is my current implementation of U (short for Union):
def U(other:FinSet[T]) = {
var otherList = other.toList
for(otherElem <- 0 until otherList.length){
this.+(otherElem)
}
this
}
When attempting to compile, it receive this error.
error: type mismatch:
found: : otherElem.type (with underlying type Int)
required : T
this.+(otherElem)
This is in class ListSet[T], which is an extension of the abstract class FinSet[T]. Both are shown here:
abstract class FinSet[T] protected () {
/* returns a list consisting of the set's elements */
def toList:List[T]
/* given a value x, it retuns a new set consisting of x
and all the elemens of this (set)
*/
def +(x:T):FinSet[T]
/* given a set other, it returns the union of this and other,
i.e., a new set consisting of all the elements of this and
all the elements of other
*/
def U(other:FinSet[T]):FinSet[T]
/* given a set other, it returns the intersection of this and other,
i.e., a new set consisting of all the elements that occur both
in this and in other
*/
def ^(other:FinSet[T]):FinSet[T]
/* given a set other, it returns the difference of this and other,
i.e., a new set consisting of all the elements of this that
do not occur in other
*/
def \(other:FinSet[T]):FinSet[T]
/* given a value x, it retuns true if and only if x is an element of this
*/
def contains(x: T):Boolean
/* given a set other, it returns true if and only if this is included
in other, i.e., iff every element of this is an element of other
*/
def <=(other:FinSet[T]):Boolean =
false // replace this line with your implementation
override def toString = "{" ++ (toList mkString ", ") ++ "}"
// overrides the default definition of == (an alias of equals)
override def equals(other:Any):Boolean = other match {
// if other is an instance of FinSet[T] then ...
case o:FinSet[T] =>
// it is equal to this iff it includes and is included in this
(this <= o) && (o <= this)
case _ => false
}
}
And here, ListSet:
class ListSet[T] private (l: List[T]) extends FinSet[T] {
def this() = this(Nil)
// invariant: elems is a list with no repetitions
// storing all of the set's elements
private val elems = l
private def add(x:T, l:List[T]):List[T] = l match {
case Nil => x :: Nil
case y :: t => if (x == y) l else y :: add(x, t)
}
val toList =
elems
def +(x: T) =
this.toList.+(x)
def U(other:FinSet[T]) = {
var otherList = other.toList
for(otherElem <- 0 until otherList.length){
this.+(otherElem)
}
this
}
def ^(other:FinSet[T]) =
this
def \(other:FinSet[T]) =
this
def contains(x:T) =
false
}
Am I missing something obvious here?

In your for loop you are assigning Ints to otherElem (x until y produces a Range[Int], which effectively gives you an iteration over the Ints from x up to y), not members of otherList. What you want is something like:
def U(other:FinSet[T]) = {
for(otherElem <- other.toList){
this.+(otherElem)
}
this
}
EDIT:
Curious, given your definitions of FinSet and ListSet (which I didn't see until after giving my initial answer), you ought to have some other issues with the above code (+ returns a List, not a FinSet, and you don't capture the result of using + anywhere, so your final return value of this ought to just return the original value of the set - unless you are not using the standard Scala immutable List class? If not, which class are you using here?). If you are using the standard Scala immutable List class, then here is an alternative to consider:
def U(other:FinSet[T]) = new ListSet((this.toList ++ other.toList).distinct)
In general, it looks a bit like you are going to some trouble to produce mutable versions of the data structures you are interested in. I strongly encourage you to look into immutable data structures and how to work with them - they are much nicer and safer to work with once you understand the principles.

Related

What updates the inherited Map of PrefixMap?

Running the PrefixMap example from the book Programming in Scala, 3rd edition, from the chapter The Architecture of Scala Collections, I don't understand what updates the inherited Map of PrefixMap when calling update.
Here is the code:
import collection._
class PrefixMap[T]
extends mutable.Map[String, T]
with mutable.MapLike[String, T, PrefixMap[T]] {
val id: Long = PrefixMap.nextId
var suffixes: immutable.Map[Char, PrefixMap[T]] = Map.empty
var value: Option[T] = None
def get(s: String): Option[T] =
if (s.isEmpty) value
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 =>
suffixes = suffixes + (leading -> empty)
case _ =>
}
val ret = suffixes(leading) withPrefix (s substring 1)
println("withPrefix: ends with: id="+this.id+", size="+this.size+", this="+this)
ret
}
override def update(s: String, elem: T) = {
println("update: this before withPrefix: id="+this.id+", size="+this.size+", return="+this)
val pm = withPrefix(s)
println("update: withPrefix returned to update: id="+pm.id+", size="+pm.size+", return="+pm)
println("===> update: this after withPrefix and before assignment to pm.value : id="+this.id+", size="+this.size+", return="+this)
pm.value = Some(elem)
println("===> update: this after assinment to pm.value: id="+this.id+", size="+this.size+", return="+this)
}
override def remove(s: String): Option[T] =
if (s.isEmpty) { val prev = value; value = None; prev }
else suffixes get s(0) flatMap (_.remove(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 -= (s: String): this.type = { remove(s); this }
override def empty = new PrefixMap[T]
}
object PrefixMap {
var ids: Long = 0
def nextId: Long = { PrefixMap.ids+=1; ids }
}
object MyApp extends App {
val pm = new PrefixMap[Int]
pm.update("a", 0)
println(pm)
}
The output is:
update: this before withPrefix: id=1, size=0, return=Map()
withPrefix: ends with: id=1, size=0, this=Map()
update: withPrefix returned to update: id=2, size=0, return=Map()
===> update: this after withPrefix and before assignment to pm.value : id=1, size=0, return=Map()
===> update: this after assinment to pm.value: id=1, size=1, return=Map(a -> 0)
Map(a -> 0)
So the question is: how it is possible that the line with "pm.value = Some(elem)" in the update method causes the inherited Map of PrefixMap to be updated with (a -> 0)?
It is not clear what you mean by "inherited Map of PrefixMap". Map is a trait which if you are coming from the Java world is similar to interface. It means that Map on its own doesn't hold any value, it just specifies contract and provides some default implementation of various convenience methods via "core" methods (the ones you implement in your PrefixMap).
As to how this whole data structure works, you should imagine this PrefixMap implementation as a "tree". Logically each edge has a single char (in the prefix sequence) and each node potentially a value that corresponds to a string that is created by accumulation all chars on the way from the root to the current node.
So if you have a Map with "ab" -> 12 key-value, the tree will look something like this:
And if you add "ac" -> 123 to the tree, it will become
Finally if you add "a" -> 1 to the tree, it will become:
Important observation here is that if you take the "a" node as a root, what you'll be left with is a valid prefix tree with all strings shortened by that "a" prefix.
Physically the layout is a bit different:
There is the root node which is PrefixMap[T] which is Map[String,T] from the outside, and also a node for an empty string key.
Internal nodes which are value + suffixes i.e. optional value and merged list of children nodes with their corresponding characters on the edge into a Map[Char, PrefixMap[T]]
As you may see update implementation is effectively find something with withPrefix call and then assigning value to it. So what the withPrefix method does? Although it is implemented recursively, it might be easier to think about it in an iterative way. From this point of view, it iterates over the characters of the given String one by one and navigates through the tree creating missing nodes see
case None =>
suffixes = suffixes + (leading -> empty)
and finally returns the node corresponding to the whole String (i.e. this in case the deepest recursive s.isEmpty)
Method get implementation is actually quite similar to the withPrefix: it recursively iterates over given string and navigates through the tree but it is simpler because it doesn't have to create missing nodes. Because children nodes are actually also stored in a Map its get method returns Option the same way PrefixMap should return Option. So you can just use flatMap and it will work OK if there is no such child node at some level.
Finally iterator creates its iterator as a union of
the value.iterator (luckily Option in Scala implements iterator that returns just 1 or 0 elements depending on whether there is a value or not)
all iterators of all the children nodes just adding its own character as a prefix to their keys.
So when you do
val pm = new PrefixMap[Int]
pm.update("a", 0)
println(pm)
update creates are node(s) in the tree and stores the value. And pm.toString actually uses iterate to build string representation. So it iterates over the tree collection all the values in non-empty value Options in all the nodes.

Contains() acting different on List and TreeSet

I've run into a weird case where the contains() function seems to work differently between a List and a TreeSet in Scala and I am not sure why or how to resolve it.
I've created a class called DataStructure for sake of brevity. It contains two elements: a coordinate pair (i, j) and an Int. (It's more complicated than that, but in this MWE, this is what it looks like) It has a custom comparator that will sort by the Int, and I have overridden hashCode and equals so that two elements containing the same coordinate pair (i, j) are treated as equal regardless of the Int.
When I put an instance of DataStructure into both a List and a TreeSet, the program has no problem finding exact matches. However, when checking for a new element that has the same coordinate pair, but different Int, the List.contains returns true while TreeSet.contains returns false. Why does this happen and how can I resolve it?
This is my code reduced to a minimum working example:
Class DataStructure
package foo
class DataStructure(e1: (Int, Int), e2: Int) extends Ordered[DataStructure] {
val coord: (Int, Int) = e1
val cost: Int = e2
override def equals(that: Any): Boolean = {
that match {
case that: DataStructure => if (that.coord.hashCode() == this.coord.hashCode()) true else false
case _ => false
}}
override def hashCode(): Int = this.coord.hashCode()
def compare(that: DataStructure) = {
if (this.cost == that.cost)
0
else if (this.cost > that.cost)
-1 //reverse ordering
else
1
}
}
Driver program
package runtime
import foo.DataStructure
import scala.collection.mutable.TreeSet
object Main extends App {
val ts = TreeSet[DataStructure]()
val a = new DataStructure((2,2), 2)
val b = new DataStructure((2,3), 1)
ts.add(a)
ts.add(b)
val list = List(a, b)
val listRes = list.contains(a) // true
val listRes2 = list.contains(new DataStructure((2,2), 0)) // true
val tsRes = ts.contains(a) // true
val tsRes2 = ts.contains(new DataStructure((2,2), 0)) // FALSE!
println("list contains exact match: " + listRes)
println("list contains match on first element: " + listRes2)
println("TreeSet contains exact match: " + tsRes)
println("TreeSet contains match on first element: " + tsRes2)
}
Output:
list contains exact match: true
list contains match on first element: true
TreeSet contains exact match: true
TreeSet contains match on first element: false
Almost certainly List.contains is checking equals for each element to find a match, whereas TreeSet.contains is walking the tree and using compare to find a match.
Your problem is that your compare is not consistent with your equals. I don't know why you're doing that, but don't:
https://www.scala-lang.org/api/current/scala/math/Ordered.html
"It is important that the equals method for an instance of Ordered[A] be consistent with the compare method."

scala view filter not lazy?

While trying to understand the differences between streams, iterators, and views of collections, I stumbled upon the following strange behavior.
Here the code (map and filter simply print their input and forward it unchanged):
object ArrayViewTest {
def main(args: Array[String]) {
val array = Array.range(1,10)
print("stream-map-head: ")
array.toStream.map(x => {print(x); x}).head
print("\nstream-filter-head: ")
array.toStream.filter(x => {print(x); true}).head
print("\niterator-map-head: ")
array.iterator.map(x => {print(x); x}).take(1).toArray
print("\niterator-filter-head: ")
array.iterator.filter(x => {print(x); true}).take(1).toArray
print("\nview-map-head: ")
array.view.map(x => {print(x); x}).head
print("\nview-filter-head: ")
array.view.filter(x => {print(x); true}).head
}
}
And its output:
stream-map-head: 1
stream-filter-head: 1
iterator-map-head: 1
iterator-filter-head: 1
view-map-head: 1
view-filter-head: 123456789 // <------ WHY ?
Why does filter called on a view process the whole array?
I expected that the evaluation of filter is driven only once by calling head, just as in all other cases, in particular just as in using map on view.
Which insight am I missing ?
(Mini-side-question for a comment, why is there no head on an iterator?)
edit:
The same strange behavior (as here for scala.Array.range(1,10)) is achieved by scala.collection.mutable.ArraySeq.range(1,10), scala.collection.mutable.ArrayBuffer.range(1,10), and scala.collection.mutable.StringBuilder.newBuilder.append("123456789").
However, for all other mutable collections, and all immutable collections, the filter on the view works as expected and outputs 1.
It seems the head uses isEmpty
trait IndexedSeqOptimized[+A, +Repr] extends Any with IndexedSeqLike[A, Repr] { self =>
...
override /*IterableLike*/
def head: A = if (isEmpty) super.head else this(0)
And isEmpty uses length
trait IndexedSeqOptimized[+A, +Repr] extends Any with IndexedSeqLike[A, Repr] { self =>
...
override /*IterableLike*/
def isEmpty: Boolean = { length == 0 }
The implementation of length is used from Filtered which loops through the whole array
trait Filtered extends super.Filtered with Transformed[A] {
protected[this] lazy val index = {
var len = 0
val arr = new Array[Int](self.length)
for (i <- 0 until self.length)
if (pred(self(i))) {
arr(len) = i
len += 1
}
arr take len
}
def length = index.length
def apply(idx: Int) = self(index(idx))
}
The Filtered trait is only used when calling filter
protected override def newFiltered(p: A => Boolean): Transformed[A] =
new { val pred = p } with AbstractTransformed[A] with Filtered
This is why is happens when using filter and not when using map
I think it has to do that Array is a mutable indexed sequence. And it's view is also a mutable collection :) So when it creates a view it creates an index that maps between original collection and filtered collection. And it doesn't really make sense to create this index lazily, because when someone will request the ith element than the whole source array may be traversed anyway. It is still lazy in a sense that this index is not created until you call head. Still this is not explicitly stated in scala documentation, and it looks like a bug at first sight.
For the mini side question, I think the problem with head on iterator is that people expect head to be pure function, namely you should be able to call it n times and it should return the same result each time. And iterator is inherently mutable data structure, which by contract is only traversable once. This may be overcomed by caching the first element of the iterator, but I find this to be very confusing.

How to determine if an expression passed to a macro will always result in the same value?

Let's suppose I've defined a macro as below. It essentially types an expression of type T and returns an object of type MyType[T] (the actual types involved don't really matter).
object MyMacro {
def macroImpl[T : context.WeakTypeTag, U : context.WeakTypeTag](context : scala.reflect.macros.blackbox.Context) (expression : context.Expr[T]) : context.Expr[U] =
}
object MyObj {
def callMacro[T](expression : T) : MyType[T] = macro MyMacro.macroImpl[T, MyType[T]]
}
In my macro, I'd like to determine if the expression passed is constant or not. By that I mean, I want to know if the expression, once evaluated at runtime, could ever subsequently evaluate to a different value. If it is constant, I can apply certain optimizations that are very useful.
I know an expression is constant if it is:
a literal expression.
a 'this' expression.
a reference to a val or parameter.
a member invocation where the object expression is constant, and the member being invoked is a val or lazy val.
For example, the expressions passed in the first five calls to callMacro below should be considered a constant:
class MyClass {
val i = 0
val myLiteral = callMacro("Hi!") //constant - literal expression
val myThis = callMacro(this) //constant - this expression
val myInt = callMacro(i) //constant - reference to a val
def myMethod(p : MyOtherClass) {
val myParameter = callMacro(p) //constant - reference to a parameter
val myValMember = callMacro(p.x) //constant - invocation of val member
val myVarMember = vallMacro(p.y) //NOT constant - invocation of var member
val myVarMember = vallMacro(p.z) //NOT constant - invocation of def member
}
}
class MyOtherClass(val x : Int, var y : Int) {
def z = x + y
}
I've already implemented code for the first two cases (which is rather trivial).
def isConstant[T](context : scala.reflect.macros.blackbox.Context) (expression : context.Expr[T]) = {
import context.universe._
expression.tree match {
case This(_) =>
true
case Literal(_) =>
true
/*...put additional cases here...*/
case _ =>
false
}
}
However, I'm not sure whether something like this already exists, or if its even possible to detect whether the member being called on an object is a val or not.
Is it possible to implement the fourth criteria? Or, does anything like this already exist in the API?
I figured out a solution. It basically boiled down to me not knowing about Symbols in scale's reflection system.
I ended up adding a fifth criteria to handle the case in which an implicit parameter or object is referenced.
implicit class extendSymbol(symbol : scala.reflect.macros.blackbox.Context#Symbol) {
def isStable =
(symbol.isTerm && symbol.asTerm.isStable) || (symbol.isMethod && symbol.asMethod.isStable)
}
def isConstant[T](context : scala.reflect.macros.blackbox.Context) (tree : context.Tree) : Boolean = {
import context.universe._
tree match {
case This(_) =>
true
case Literal(_) =>
true
case ident # Ident(_) =>
ident.symbol.isStable
case select # Select(objExpr, term) =>
isConstant(context) (objExpr) && select.symbol.isStable
//for implicit values
case Apply(TypeApply(Select(Select(This(TypeName("scala")), TermName("Predef")), TermName("implicitly")), _), _) =>
true
case _ =>
false
}
}

Type mismatch from partition in Scala (expected (Set[String]...), actual (Set[String]...) )

I have a partition method that creates tuple of two sets of string.
def partition(i:Int) = {
dictionary.keySet.partition(dictionary(_)(i) == true)
}
I also have a map that maps integer to the return value from the partition method.
val m = Map[Int, (Set[String], Set[String])]()
for (i <- Range(0, getMaxIndex())) {
m(i) = partition(i)
}
The issue is that I have type mismatch error, but the error message does not make sense to me.
What might be wrong?
This is the code:
import scala.collection.mutable.Map
import scala.collection.{BitSet}
case class Partition(dictionary:Map[String, BitSet]) {
def max(x:Int, y:Int) = if (x > y) x else y
def partition(i:Int) = {
dictionary.keySet.partition(dictionary(_)(i) == true)
}
def getMaxIndex() = {
val values = dictionary.values
(0 /: values) ((m, bs) => max(m, bs.last))
}
def get() = {
val m = Map[Int, (Set[String], Set[String])]()
for (i <- Range(0, getMaxIndex())) {
m(i) = partition(i)
}
m
}
}
When I compile your example, the error is clear:
<console>:64: error: type mismatch;
found : (scala.collection.Set[String], scala.collection.Set[String])
required: (scala.collection.immutable.Set[String], scala.collection.immutable.Set[String])
m(i) = partition(i)
^
Looking into the API, the keySet method of a mutable map does not guarantee that the returned set is immutable. Compare this with keySet on an immutable Map—it does indeed return an immutable set.
Therefore, you could either
use an immutable Map and a var
force the result of your partition method to return an immutable set (e.g. toSet)
define the value type of your map to be collection.Set instead of Predef.Set which is an alias for collection.immtuable.Set.
To clarify these types, it helps to specify an explicit return type for your public methods (get and partition)