Red black trees with classes in OCaml - class

Does anyone know how to implement red black trees with classes in OCaml?
At least the class properties and initializers? I'm new in OCaml.
What I tried:
type data = {key: int; value: string}
class node (data: data) =
object (self)
val mutable d = data
val mutable color = 1
val mutable left = ref (None: node option)
val mutable right = ref (None: node option)
val mutable parent = ref (None: node option)
method getLeft = left
method getRight = right
method getParent = parent
method getColor = color
method getData = d
method setLeft (l: node option ref) = left := !l
method setRight (l: node option ref) = right := !l
method setParent (l: node option ref) = parent := !l
end;;
class rbtree =
object (self)
val mutable root = ref (None: node option)
val mutable nullNode = ref (None: node option)
method searchNode (aNode: node option ref) (key: data) = begin
if aNode = nullNode || key == (!aNode)#getData then aNode;
end;
end;;
I get the error This expression has type node option
It has no method getData
What I am trying is to make something like this code that is written in C++:
struct Node
{
int data;
Node *parent;
Node *left;
Node *right;
int color;
};
typedef Node *NodePtr;
class RedBlackTree
{
private:
NodePtr root;
NodePtr TNULL;
void initializeNULLNode(NodePtr node, NodePtr parent)
{
node->data = 0;
node->parent = parent;
node->left = nullptr;
node->right = nullptr;
node->color = 0;
}
NodePtr searchTreeHelper(NodePtr node, int key)
{
if (node == TNULL || key == node->data)
{
return node;
}
if (key < node->data)
{
return searchTreeHelper(node->left, key);
}
return searchTreeHelper(node->right, key);
}
};

For the error you're seeing, #Shon is correct. You have this expression:
if aNode = nullNode || key == (!aNode)#getData then aNode;
The type of aNode is node option ref. So that means the type of !anode is node option. An option value isn't an object (an instance of a class). So you can't call the method getData on it.
Again, as #Shon says, you need to retrieve the value of !aNode (if there is one). This will give you a node, which is an object and does have a getData method.
It would be messy to write this code in-line in your if test. So you might write a function like this:
let node_option_has_value node_opt value =
match node_opt with
| None -> false
| Some node -> node#getData = value
As a side comment, you should not be using the physical equality operator (==) to do comparisons. This operator is for special cases, not for general use.
The equality comparison operator in OCaml is = (as in my example code).

Related

scala case class hashcode with circular references

As Scala documentation says, "Case classes are compared by structure and not by reference".
I was trying to create a linked list with a loop in it, then add a node from this looped list to a mutable set. When using a regular class, it succeeded, but with a case class I hit a stack overflow.
I'm curious why Scala doesn't first check for reference before checking for structure. My thinking is that that if the reference is the same then the structure is guaranteed to be the same, so this can be a shortcut as well as allow for circular references.
Code:
object CaseClassHashcodeExample {
def main(args: Array[String]): Unit = {
val head = new ListNode(0)
head.appendToTail(1)
head.appendToTail(2)
head.appendToTail(3)
head.next.next.next = head.next
val set = collection.mutable.Set[ListNode]()
set.add(head)
assert(set(head))
}
}
case class ListNode(var data: Int, var next: ListNode = null) {
def appendToTail(d: Int): Unit = {
val end = new ListNode(d)
var cur = this
while (cur.next != null)
cur = cur.next
cur.next = end
}
}
I'm curious why Scala doesn't first check for reference before checking for structure
Well, what exactly do you want it to check? The current generated code looks something like
def hashCode() = 31 * data.hashCode() + next.hashCode()
One thing you could try is
def hashCode() = 31 * data.hashCode() + (if (next eq this) 0 else next.hashCode())
but it wouldn't actually help: in your case it isn't next which is the same as this, it's next.next.
next.hashCode doesn't know it's called from this.hashCode and so can't compare its own next to this.
You could create a helper method taking a set of "seen" objects into account:
def hashCode() = hashCode(Nil)
def hashCode(seen: List[ListNode]) = if (seen.exists(_ eq this)) 0 else 31 * data.hashCode() + next.hashCode(this :: seen)
But this both greatly slows down the common case, and is hard to actually get right.
EDIT: for equals, reference equality is checked first in case classes.
class NeverEq {
override def equals(other: Any) = false
}
case class Test(x: NeverEq)
val x = Test(new NeverEq())
println(x == x)
prints true and would be false if only structure was compared.
But it doesn't actually help with circular references. Let's say you have a ListNode type without data to simplify which implements equality like this:
def equals(other: Any) = (this eq other) || (other match {
case other: ListNode => this.next == other.next
})
and want to check if node1 == node2 where node1.next is node2 and vice versa:
node1 <--> node2
node1 == node2 reduces to (node1 eq node2) || (node1.next == node2.next).
node1 eq node2 is false, so that reduces to node1.next == node2.next, that is node2 == node1.
node2 eq node1 is false, so that reduces to node2.next == node1.next, that is node1 == node2...

Genie Vala Generics and Nullable Types

Simple question: In the following generic class, how should the generic type and contained types be defined so that they are nullable? The following will not compile.
class Pair? of G1, G2: Object
_first:G1?
_second:G2?
construct()
_first = null
_second = null
def insert( first:G1, second:G2 )
_first = first
_second = second
def insert_first( value:G1 )
_first = value
def insert_second( value:G2 )
_second = value
def second():G2
return _second
Usage:
var pair = new Pair() of string, string
pair = null
Due to the way Vala Generics work, generic parameters are always nullable.
As long as you don't switch on --enable-experimental-non-null class variables are nullable as well, so your code simplifies to:
[indent=4]
class Pair of G1, G2: Object
_first:G1
_second:G2
construct()
_first = null
_second = null
def insert( first:G1, second:G2 )
_first = first
_second = second
def insert_first( value:G1 )
_first = value
def insert_second( value:G2 )
_second = value
def second():G2
return _second
init
var pair = new Pair of string, string
pair = null
When --enable-experimental-non-null is on, you have to be explicit in the type of the variable. I don't know how to write this in Genie, I tried this, but the compiler does not like it:
init
pair: Pair? of string, string = new Pair of string, string
pair = null
In Vala it's no problem:
class Pair<G1,G2>: Object {
private G1 first;
private G2 second;
public Pair () {
first = null;
second = null;
}
// ...
}
int main () {
Pair<string, string>? pair = new Pair<string, string> ();
pair = null;
return 0;
}
I can't wrap my head around the concept of a type parameter that has null as the type. I don't think that is a useful concept. So the definition of your class would be:
[indent = 4]
class Pair of G1, G2: Object
_first:G1?
_second:G2?
def insert( first:G1, second:G2 )
_first = first
_second = second
def insert_first( value:G1 )
_first = value
def insert_second( value:G2 )
_second = value
def second():G2
return _second
If you must re-assign the variable that has the object instance to null then it would be:
[indent = 4]
init
var pair = new Pair of string,string()
pair = null
The Vala compiler will, however, dereference pair when it goes out of scope. So I'm not sure why you would need to assign null.
The use of nulls would ideally only be used when interfacing with a C library in my view. Accessing a null can lead to a crash (segmentation fault) if it is not checked for properly. For example:
init
a:int? = 1
a = null
var b = a + 1
The Vala compiler does have an experimental non-null mode that does some checking for unsafe code. If you compile the following with the Vala switch --enable-experimental-non-null:
[indent = 4]
init
var pair = new Pair of string,string()
pair = null
you will get the error:
error: Assignment: Cannot convert fromnull' to Pair<string,string>'
If you understand the consequences then you can tell the compiler this is OK with:
[indent = 4]
init
pair:Pair? = new Pair of string,string()
pair = null

How to mimic Scala's Map/Array assignment syntax in my own class

Following is a simple map entry assignment:
scala> var myl = mutable.Map[String,String]()
myl: scala.collection.mutable.Map[String,String] = Map()
myl("abc") = "123"
I would like to mimic that assignment structure in my own class that works with mutable Tuple's. Now, "getting" a value from a Map is achieved via the "apply" method:
e.g mutable.HashMap:
override def apply(key: A): B = {
val result = findEntry(key)
if (result eq null) default(key)
else result.value
}
I was not however able to find how the map entry is "set" via myMap("myKey") = "myval". A pointer to the Scala source code to do that would be appreciated. Thanks.
The method you want to implement is called update() and takes two parameters, one for the input value passed in parentheses and the other for the assigned value.
class QueryParams {
var params = ""
def update(name: String, value: String) { params += s"$name=$value&" }
}
For example:
val p = new QueryParams()
p("q") = "SFO"
p("start") = "10"
p("rows") = "10"
p.params

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

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.

Scala Properties Question

I'm still learning Scala, but one thing I thought was interesting is that Scala blurs the line between methods and fields. For instance, I can build a class like this...
class MutableNumber(var value: Int)
The key here is that the var in the constructor-argument automatically allows me to use the 'value' field like a getter/setter in java.
// use number...
val num = new MutableNumber(5)
num.value = 6
println(num.value)
If I want to add constraints, I can do so by switching to using methods in place of the instance-fields:
// require all mutable numbers to be >= 0
class MutableNumber(private var _value: Int) {
require(_value >= 0)
def value: Int = _value
def value_=(other: Int) {
require(other >=0)
_value = other
}
}
The client side code doesn't break since the API doesn't change:
// use number...
val num = new MutableNumber(5)
num.value = 6
println(num.value)
My hang-up is with the named-parameter feature that was added to Scala-2.8. If I use named-parameters, my API does change and it does break the api.
val num = new MutableNumber(value=5) // old API
val num = new MutableNumber(_value=5) // new API
num.value = 6
println(num.value)
Is there any elegant solution to this? How should I design my MutableNumber class so that I can add constraints later on without breaking the API?
Thanks!
You can use the same trick that case classes do: use a companion object.
object Example {
class MutableNumber private (private var _value: Int) {
require (_value >= 0)
def value: Int = _value
def value_=(i: Int) { require (i>=0); _value = i }
override def toString = "mutable " + _value
}
object MutableNumber {
def apply(value: Int = 0) = new MutableNumber(value)
}
}
And here it is working (and demonstrating that, as constructed, you must use the object for creations, since the constructor is marked private):
scala> new Example.MutableNumber(5)
<console>:10: error: constructor MutableNumber cannot be accessed in object $iw
new Example.MutableNumber(5)
^
scala> Example.MutableNumber(value = 2)
res0: Example.MutableNumber = mutable 2
scala> Example.MutableNumber()
res1: Example.MutableNumber = mutable 0
Thanks for the answer! As an aside, I think the Scala-guys might be aware that there's an issue:
What's New in Scala 2.8: Named and Default Parameters
...
Until now, the names of arguments were a somewhat arbitrary choice for library developers, and weren't considered an important part of the API. This has suddenly changed, so that a method call to mkString(sep = " ") will fail to compile if the argument sep were renamed to separator in a later version.
Scala 2.9 implements a neat solution to this problem, but while we're waiting for that, be cautious about referring to arguments by name if their names may change in the future.
http://www.artima.com/scalazine/articles/named_and_default_parameters_in_scala.html
class MutableNumber {
private var _value = 0 //needs to be initialized
def value: Int = _value
def value_=(other: Int) {
require(other >=0) //this requirement was two times there
_value = other
}
}
you can modify all members of any class within curly braces
val n = new MutableNumber{value = 17}