How to associate an iterator to a collection in OCaml - class

I have these two classes in OCaml
class type ['a] collection =
object
method add : 'a -> unit
method clear : unit -> unit
method iterator : unit -> 'a iterator
method remove : 'a -> unit
end
class type ['a] iterator =
object
method hasNext : unit -> bool
method next : unit -> 'a
end
And I need to create two concrete classes ['a] queue subtype of collection and ['a] iterator_queue a subtype of iterator.
I want mainly to know how to define the method iterator : unit -> 'a iterator because I don't see how the two types can be connected, Does the ['a] iterator_queue has to be inherited from both the abstract ones? or should I proceed differently.

Probably the easiest way to do this is to define the iterator as an object within the scope of the definition of the queue (in Java, this would be called an "inner class"). For example:
class ['a] queue : ['a] collection =
object
val q = ref []
(* definitions of add, clear, remove *)
method iterator () : 'a iterator =
object
val lst = ref !q
(* definitions of hasNext and next *)
end
end
Note that lst is a reference to the (immutable) value of q at the time that iterator is called. Subsequent changes to the queue won't be reflected in the iterator.

I suspect this might simply be a test of mutually recursive class definitions.
class ['a] queue =
object
inherit 'a container
method iterator = new iterator_queue args
...
end
and ['a] iterator_queue args =
object
...
end

Related

How does Scala transform case classes to be accepted as functions?

I am trying to understand how a case class can be passed as an argument to a function which accepts functions as arguments. Below is an example:
Consider the below function
def !![B](h: Out[B] => A): In[B] = { ... }
If I understood correctly, this is a polymorphic method which has a type parameter B and accepts a function h as a parameter. Out and In are other two classes defined previously.
This function is then being used as shown below:
case class Q(p: boolean)(val cont: Out[R])
case class R(p: Int)
def g(c: Out[Q]) = {
val rin = c !! Q(true)_
...
}
I am aware that currying is being used to avoid writing the type annotation and instead just writing _. However, I cannot grasp why and how the case class Q is transformed to a function (h) of type Out[B] => A.
EDIT 1 Updated !! above and the In and Out definitions:
abstract class In[+A] {
def future: Future[A]
def receive(implicit d: Duration): A = {
Await.result[A](future, d)
}
def ?[B](f: A => B)(implicit d: Duration): B = {
f(receive)
}
}
abstract class Out[-A]{
def promise[B <: A]: Promise[B]
def send(msg: A): Unit = promise.success(msg)
def !(msg: A) = send(msg)
def create[B](): (In[B], Out[B])
}
These code samples are taken from the following paper: http://drops.dagstuhl.de/opus/volltexte/2016/6115/
TLDR;
Using a case class with multiple parameter lists and partially applying it will yield a partially applied apply call + eta expansion will transform the method into a function value:
val res: Out[Q] => Q = Q.apply(true) _
Longer explanation
To understand the way this works in Scala, we have to understand some fundamentals behind case classes and the difference between methods and functions.
Case classes in Scala are a compact way of representing data. When you define a case class, you get a bunch of convenience methods which are created for you by the compiler, such as hashCode and equals.
In addition, the compiler also generates a method called apply, which allows you to create a case class instance without using the new keyword:
case class X(a: Int)
val x = X(1)
The compiler will expand this call to
val x = X.apply(1)
The same thing will happen with your case class, only that your case class has multiple argument lists:
case class Q(p: boolean)(val cont: Out[R])
val q: Q = Q(true)(new Out[Int] { })
Will get translated to
val q: Q = Q.apply(true)(new Out[Int] { })
On top of that, Scala has a way to transform methods, which are a non value type, into a function type which has the type of FunctionX, X being the arity of the function. In order to transform a method into a function value, we use a trick called eta expansion where we call a method with an underscore.
def foo(i: Int): Int = i
val f: Int => Int = foo _
This will transform the method foo into a function value of type Function1[Int, Int].
Now that we posses this knowledge, let's go back to your example:
val rin = c !! Q(true) _
If we just isolate Q here, this call gets translated into:
val rin = Q.apply(true) _
Since the apply method is curried with multiple argument lists, we'll get back a function that given a Out[Q], will create a Q:
val rin: Out[R] => Q = Q.apply(true) _
I cannot grasp why and how the case class Q is transformed to a function (h) of type Out[B] => A.
It isn't. In fact, the case class Q has absolutely nothing to do with this! This is all about the object Q, which is the companion module to the case class Q.
Every case class has an automatically generated companion module, which contains (among others) an apply method whose signature matches the primary constructor of the companion class, and which constructs an instance of the companion class.
I.e. when you write
case class Foo(bar: Baz)(quux: Corge)
You not only get the automatically defined case class convenience methods such as accessors for all the elements, toString, hashCode, copy, and equals, but you also get an automatically defined companion module that serves both as an extractor for pattern matching and as a factory for object construction:
object Foo {
def apply(bar: Baz)(quux: Corge) = new Foo(bar)(quux)
def unapply(that: Foo): Option[Baz] = ???
}
In Scala, apply is a method that allows you to create "function-like" objects: if foo is an object (and not a method), then foo(bar, baz) is translated to foo.apply(bar, baz).
The last piece of the puzzle is η-expansion, which lifts a method (which is not an object) into a function (which is an object and can thus be passed as an argument, stored in a variable, etc.) There are two forms of η-expansion: explicit η-expansion using the _ operator:
val printFunction = println _
And implicit η-expansion: in cases where Scala knows 100% that you mean a function but you give it the name of a method, Scala will perform η-expansion for you:
Seq(1, 2, 3) foreach println
And you already know about currying.
So, if we put it all together:
Q(true)_
First, we know that Q here cannot possibly be the class Q. How do we know that? Because Q here is used as a value, but classes are types, and like most programming languages, Scala has a strict separation between types and values. Therefore, Q must be a value. In particular, since we know class Q is a case class, object Q is the companion module for class Q.
Secondly, we know that for a value Q
Q(true)
is syntactic sugar for
Q.apply(true)
Thirdly, we know that for case classes, the companion module has an automatically generated apply method that matches the primary constructor, so we know that Q.apply has two parameter lists.
So, lastly, we have
Q.apply(true) _
which passes the first argument list to Q.apply and then lifts Q.apply into a function which accepts the second argument list.
Note that case classes with multiple parameter lists are unusual, since only the parameters in the first parameter list are considered elements of the case class, and only elements benefit from the "case class magic", i.e. only elements get accessors implemented automatically, only elements are used in the signature of the copy method, only elements are used in the automatically generated equals, hashCode, and toString() methods, and so on.

Scala's apply method

I am constructing a List in Scala as below:
val list1 = List(1,2,3) //This is otherwise: List.apply(1,2,3) ---> A
Now I have the below line.
list1(1) //which is otherwise list1.apply(1) ---> B
Above line returns 2 which is of type Int.
Line A and B are calls to apply method in the List class. Method overloading certainly can not be present in List class. Then based on what the compiler treats A and B differently ?
Can anyone please help me to understand this.
Thanks!
There are two different types at play here. In your second example, you are calling the apply instance method on your instance of the List class. In your first example, you aren't calling anything on the List class at all, you are calling the apply method on the List companion object.
in the line
val list1 = List(1,2,3)
You can tell that in this context you are calling a method on the companion object because you don't have an instance of List and are seemingly calling apply on the class itself.
There are two apply methods here: the List.apply and LinearSeqOptimized.apply. The main difference is, when you call List(1, 2, 3) you're using List companion object apply method and, when you call list1(1) you're using the apply's method inherited from LinearSeqOptimized trait (which List class inherits from).
Above answers explains the reasons well. Let me explain it in more details.
When you invoke val list1 = List(1,2,3), you are invoking a object List which is a companion object of class List and which in turns invoke .apply() method and return instance of class List.
override def apply[A](xs: A*): List[A] = xs.toList //return instance of class List.
Now, if you look into class List:
sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqOptimized[A, List[A]] {...}
You can see that it inherit trait LinearSeqOptimized[A, List[A]]. And if you look into this trait you can see an apply() method as
/** Selects an element by its index in the $coll.
* Note: the execution of `apply` may take time proportional to the index value.
* #throws IndexOutOfBoundsException if `idx` does not satisfy `0 <= idx < length`.
*/
def apply(n: Int): A = {
val rest = drop(n)
if (n < 0 || rest.isEmpty) throw new IndexOutOfBoundsException("" + n)
rest.head
}
That means, class List will also inherit this .apply method. Therefore, when you invoke list1(1), you are actually invoking this apply method, which return particular index value of the list.
To conclude, in first code, you are invoking .apply method of companion object List which create list and return instance of class List and in second case, you are invoking .apply method of class List which return particular value of that list.

Is cons a method or a class?

Marting Odersky in his book writes:
Class ::, pronounced “cons” for “construct,” represents non-empty lists.
and
The list construction methods :: and ::: are special. Because they end
in a colon, they are bound to their right operand. That is, an
operation such as x :: xs is treated as the method call xs.::(x), not
x.::(xs). In fact, x.::(xs) would not make sense, as x is of the list
element type, which can be arbitrary, so we cannot assume that this
type would have a :: method. For this reason, the :: method should
take an element value and yield a new list
So is :: a method or a class?
It is both a class and a method. Cons is a type parametised class. List[A] has two sub classes: Cons and Nil. As Cons is a class it can be created by its constructor as follows:
val s = new ::[Int](4, Nil)
Cons is a case class and we use the constructor when we do a pattern match. Cons is also a method on the list class that is implemented in its two sub classes. Hence we can use the cons method on the cons class that we have created above.
val s1 = s.::(5)
Part of the confusion may arise, because we normally create Lists using the apply method of the List object:
val s2 = List(1, 2, 3)
Normally the apply method of an object returns a new instance of the Class with the same name as an object. This is however just convention. In this particular case the List Object returns a new instance of the Cons subclass. The List class itself is a sealed abstract class so can not be instantiated. So the above apply method does the following:
val s2 = 1 :: 2 :: 3 :: Nil
Any method that ends in a ':' is a method on the operand to its right so it can be rewritten as
val s2 = 1 :: (2 :: (3 :: Nil)) //or as
val s2 = Nil.::(3).::(2).::(1)
So the Cons(::) method on the Nil object takes the 3 as a parameter and produces an anonymous instantiation of the Cons class with 3 as its head and a reference to the Nil object as its tail. Lets call this anonymous object c1. The Cons method is then called on c1 taking 2 as its parameter returning a new anonymous Cons instantiation lets call it c2, which has 2 for its head and a reference to c1 as its tail. Then finally the cons method on the c2 object takes the 1 as a parameter and returns the named object s2 with 1 as its head and a reference to c2 as its tail.
A second point of confusion is that the REPL and Scala worksheets use a class' toString methods to display results. So the worksheet gives us:
val s3 = List(5, 6, 7) // s3 : List[Int] = List(5, 6, 7)
val s4 = List() // s4 : List[Nothing] = List()
val s5: List[Int] = List() // s5 : List[Int] = List()
s3.getClass.getName // res3: String = scala.collection.immutable.$colon$colon
s4.getClass.getName // res4: String = scala.collection.immutable.Nil$
s5.getClass.getName // res5: String = scala.collection.immutable.Nil$
As said above List is sealed so new sub sub classes can not be created as Nil is an object and Cons is final. As Nil is an object it can't be parametrised. Nil inherits from List[Nothing]. At first glance that doesn't sound that useful but remember these data structures are immutable, so we can never add to them directly and Nothing is a sub class of every other class. So we can add the Nil class (indirectly) to any List without problem. The Cons class has two members a head and another List. Its a rather neat solution when you clock it.
I'm not sure if this has any practical use but you can use Cons as a type:
var list: ::[Int] = List (1,2,3).asInstanceOf[::[Int]]
println("Initialised List")
val list1 = Nil
list = list1.asInstanceOf[::[Int]] //this will throw a java class cast exception at run time
println("Reset List")
Short answer: both.
There is a subclass of list called ::, but you won't refer to it explicitly very often.
When you write e.g. 1 :: 2 :: Nil, the :: is a method on List, which creates an instance of the class :: behind the scenes.
:: is best thought of not as a method or a class, though, but as a constructor in the algebraic data type (ADT) sense. Wikipedia calls ADT constructors "quasi-functional entit[ies]", which makes them sound more complicated than they are, but isn't necessarily a bad way to think about them.
List has two constructors, :: (called cons in some languages) and Nil. The Wikipedia article I've linked above gives a good introduction to the idea of lists as algebraic data types.
It's worth noting that in some languages (like Haskell) ADT constructors don't have their own types associated with them—they are just functions that create an instance of the ADT.
This is typically effectively the case in Scala as well, where it's fairly rare to refer to the type of an ADT constructor like ::. It is possible, though—we can write this:
def foo(xs: ::[Int]) = ???
Or this (where Some is one of the constructors for the Option ADT).
def bar(s: Some[Int]) = ???
But this is in general not very useful, and could be considered an artifact of the way Scala implements algebraic data types.

differences between List(), Array() and new List(), new Array() in Scala

I know that when you type:
val list = List(2,3)
you are accessing the apply method of the List object which returns a List. What I can't understand is why is this possible when the List class is abstract and therefore cannot be directly instanciated(new List() won't compile)?
I'd also like to ask what is the difference between:
val arr = Array(4,5,6)
and
val arr = new Array(4, 5, 6)
The List class is sealed and abstract. It has two concreate implementations
Nil which represents an empty list
::[B] which represents a non empty list with head and tail. ::[B] in the documentation
When you call List.apply it will jump through some hoops and supply you with an instance of the ::[B] case class.
About array: new Array(4, 5, 6) will throw a compile error as the constructor of array is defined like this: new Array(_length: Int). The apply method of the Array companion object uses the arguments to create a new instance of an Array (with the help of ArrayBuilder).
I started writing that the easy way to determine this is to look at the sources for the methods you're calling, which are available from the ScalaDoc. However, the various levels of indirection that are gone through to actually build a list give lie to the term 'easy'! It's worth having a look through if you want, starting from the apply method in the List object which is defined as follows:
override def apply[A](xs: A*): List[A] = xs.toList
You may or may not know that a parameter of the form xs : A* is treated internally as a Seq, which means that we're calling the toList method on a Seq, which is defined in TraversableOnce. This then delegates to a generic to method, which looks for an implicit
CanBuildFrom which actually constructs the list. So what you're getting back is some implementation of List which is chosen by the CanBuildFrom. What you actually get is a scala.collection.immutable.$colon$colon, which implements a singly-linked list.
Luckily, the behaviour of Array.apply is a little easier to look up:
def apply[T: ClassTag](xs: T*): Array[T] = {
val array = new Array[T](xs.length)
var i = 0
for (x <- xs.iterator) { array(i) = x; i += 1 }
array
}
So, Array.apply just delegates to new Array and then sets elements appropriately.

How to use the traverse TypeClass to accumulate state based on the elements and then map over the state and elements?

What is the function that I should pass to 'traverse' (from the essence of the iterator pattern) such that I can accumulate state based on each of the original elements and then map based on the original elements and the state so far.
In 'collect' and 'disperse' only either the mapping depends on the state or the state depends on the element, but not both at the same time.
The table at http://etorreborre.blogspot.co.uk/2011/06/essence-of-iterator-pattern.html appears to say that I should use 'traverse' but traverse is the function that implements all the others, so I'm a bit lost.
When you use the traverse method with a function returning a State, you get exactly what you want:
// a function using the current element and the previous state
def function[S, T](s: S, t: T): R = // combine T and S
// return a State instance to use as an Applicative with traverse
def myState[T, S](t: T) = State[S, R]((s: S) => function(s, t))
// a sequence to traverse
val sequence: Seq[T] = ...
// use the traverse method
sequence.traverse(t => myState(t))
An example of what I wanted to do:
main = putStrLn $ show $ runState s 0
where
s = traverse f [1,2,3,4,5]
f = \x -> state( \y -> (x*20+y, y+x) )
The result is ([20,41,63,86,110],15)