Showing posts with label companion. Show all posts
Showing posts with label companion. Show all posts

Tuesday, January 3, 2012

Learning Scala : Reading the exotic and essential List API scaladoc 12

Authored by Win Myo Htet



def genericBuilder [B] : Builder[B, List[B]]
The generic builder that builds instances of List at arbitrary element types.

def groupBy [K] (f: (A) ⇒ K): Map[K, List[A]]
Partitions this list into a map of lists according to some discriminator function.
def partition (p: (A) ⇒ Boolean): (List[A], List[A])
Partitions this list in two lists according to a predicate.

def grouped (size: Int): Iterator[List[A]]
Partitions elements in fixed size lists.
def sliding [B >: A] (size: Int): Iterator[List[A]]
Groups elements in fixed size blocks by passing a "sliding window" over them (as opposed to partitioning them, as is done in grouped.
def sliding [B >: A] (size: Int, step: Int): Iterator[List[A]]
Sorts this List according to the Ordering which results from transforming an implicitly given Ordering with a transformation function.

def hasDefiniteSize : Boolean
Tests whether this list is known to have a finite size.
def hashCode (): Int
Hashcodes for List produce a value from the hashcodes of all the elements of the list.
genericBuilder return a Builder, through which we can create the same collection type, in our case List(you might want to look up a similar function, companion, covered here.) In contrast with companion function is that you have to call function result to get the desired collection(List) type from the (List)buffer.
groupBy return the-function-defined-partition of the List as a value and it is mapped to the key. We demonstrate this by partitioning the List in terms of the modulo of 3. Lists of Odd and Even partitioning is considered for the demonstration but groupBy is capable of partitioning more than two Lists unlike the following function, thus the modulo of 3 example is used.
The function partition returns two partitions, which either satisfies the predicate or not. We have a tuple of two resulting Lists: Odd List and Even List.
grouped return iterator to get a List of n elements.
sliding is better described in the code snippet.
hasDefiniteSize is to differentiate collection, like Stream, which has infinite size, and other collection, which does not have infinite size. List does not have infinite size. hashCode return hashCode.
scala> val list = (for (i <- 1 to 11) yield i) toList
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

scala> val bldr = list.genericBuilder[Int] += (5,6,7)
bldr: scala.collection.mutable.Builder[Int,List[Int]] = ListBuffer(5, 6, 7)

scala> bldr.result
res0: List[Int] = List(5, 6, 7)

scala> list.genericBuilder[String] += ("a","b","c")
res1: scala.collection.mutable.Builder[String,List[String]] = ListBuffer(a, b, c)

scala> list groupBy { case x:Int if x % 3 == 0 => "0"; case x:Int if x % 3 == 1 => "1" ; case x:Int if x % 3 == 2 => "2"}
res2: scala.collection.immutable.Map[java.lang.String,List[Int]] = Map(0 -> List(3, 6, 9), 1 -> List(1, 4, 7, 10), 2 -> List(2, 5, 8, 11))

scala> list partition ( x => x % 2 == 0)
res3: (List[Int], List[Int]) = (List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9, 11))

scala> for ( x <- list grouped 3) println(x)
List(1, 2, 3)
List(4, 5, 6)
List(7, 8, 9)
List(10, 11)

scala> for ( x <- list sliding 3) println(x)
List(1, 2, 3)
List(2, 3, 4)
List(3, 4, 5)
List(4, 5, 6)
List(5, 6, 7)
List(6, 7, 8)
List(7, 8, 9)
List(8, 9, 10)
List(9, 10, 11)

for (x <- list.sliding(4,2)) println(x)
List(1, 2, 3, 4)
List(3, 4, 5, 6)
List(5, 6, 7, 8)
List(7, 8, 9, 10)
List(9, 10, 11)

scala> list hasDefiniteSize
res6: Boolean = true

scala> list hashCode
res7: Int = -1287208638


def head : A
Selects the first element of this list.
def headOption : Option[A]
Optionally selects the first element.
def last : A
Selects the last element.
def lastOption : Option[A]
Optionally selects the last element.

def tail : List[A]
Selects all elements except the first.
def tails : Iterator[List[A]]
Iterates over the tails of this list.
def init : List[A]
Selects all elements except the last.
def inits : Iterator[List[A]]
Iterates over the inits of this list.

def isEmpty : Boolean
Tests whether the list is empty.
def nonEmpty : Boolean
Tests whether the list is not empty.
We know head and tail early when we start reading about Scala. Here we have brought their relatives together along with its counterpart family of last(head) and init(tail). isEmpty or noEmpty? These two methods serve the same purpose. The reason for two functions for a single purpose is for self-documenting. One can see that in comment of TraversableOnce source at line 62.

scala> list head
res8: Int = 1

scala> list headOption
res9: Option[Int] = Some(1)

scala> list last
res10: Int = 11

scala> list lastOption
res11: Option[Int] = Some(11)

scala>  list tail
res12: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

scala> for (x <- list tails) println(x)
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
List(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
List(3, 4, 5, 6, 7, 8, 9, 10, 11)
List(4, 5, 6, 7, 8, 9, 10, 11)
List(5, 6, 7, 8, 9, 10, 11)
List(6, 7, 8, 9, 10, 11)
List(7, 8, 9, 10, 11)
List(8, 9, 10, 11)
List(9, 10, 11)
List(10, 11)
List(11)
List()

scala> list init
res14: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> for (x <- list inits) println(x)
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
List(1, 2, 3, 4, 5, 6, 7, 8, 9)
List(1, 2, 3, 4, 5, 6, 7, 8)
List(1, 2, 3, 4, 5, 6, 7)
List(1, 2, 3, 4, 5, 6)
List(1, 2, 3, 4, 5)
List(1, 2, 3, 4)
List(1, 2, 3)
List(1, 2)
List(1)
List()

scala> list isEmpty
res16: Boolean = false

scala> list nonEmpty
res17: Boolean = true



Authored by Win Myo Htet

Friday, December 30, 2011

Learning Scala : Reading the exotic and essential List API scaladoc 9

Authored by Win Myo Htet


def apply (n: Int): A
Selects an element by its index in the list.

def canEqual (that: Any): Boolean
Method called from equality methods, so that user-defined subclasses can refuse to be equal to other collections of the same kind.

def collect [B] (pf: PartialFunction[A, B]): List[B]
[use case] Builds a new collection by applying a partial function to all elements of this list on which the function is defined.

def collect [B, That] (pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[List[A], B, That]): That
Builds a new collection by applying a partial function to all elements of this list on which the function is defined.

def collectFirst [B] (pf: PartialFunction[A, B]): Option[B]
Finds the first element of the list for which the given partial function is defined, and applies the partial function to it.

def combinations (n: Int): Iterator[List[A]]
Iterates over combinations.

def companion : GenericCompanion[List]
The factory companion object that builds instances of class List. (or its Iterable superclass where class List is not a Seq.)
apply's description is good enough and I don't think that I have to explain it. apply can also be invoked without the function name. One can read more about it in my case class blog(companion object). canEqual is for us to override for our own class, where we can defined if we are to allow two elements to evaluate  equality. List does not override it. If we look at IterableLike (line 292), from which canEqual is inherited, it simply returns true. So, List allows to do equality for all type. collect takes Partial Functions that is constructed how we we collect the elements. collectFirst just picks the nicely-wrapped-in-Option first element from the collect. combinations can be used to create Lists that has exactly the number, which is received from  combinations's parameter, of elements from the invoking List object. companion function return a factory like class GenericCompanion from which one can create a new collection of the type like List. It is explained quite nicely at SO here.
scala> val list=List(1,2,3,4,5,6,7,8,9,10)
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.apply(0)
res0: Int = 1

scala> list(0)
res1: Int = 1

scala> list.canEqual("anything")
res2: Boolean = true

scala> val even:PartialFunction[Int,Int]={case x:Int if x%2==0 =>x}
even: PartialFunction[Int,Int] = <function1>

scala> list collect even
res3: List[Int] = List(2, 4, 6, 8, 10)

scala> val pretty_even:PartialFunction[Int,String]={case x:Int if x%2==0 =>"-"+x+"-"}
pretty_even: PartialFunction[Int,String] = <function1>

scala> list collect pretty_even
res4: List[String] = List(-2-, -4-, -6-, -8-, -10-)

scala> list collectFirst pretty_even
res5: Option[String] = Some(-2-)

scala> val strList=list.companion("a","b","c","d")
strList: List[java.lang.String] = List(a, b, c, d)

scala> for(x <- strList.combinations(2)) println(x)
List(a, b)
List(a, c)
List(a, d)
List(b, c)
List(b, d)
List(c, d)

scala> for(x <- strList.combinations(3)) println(x)
List(a, b, c)
List(a, b, d)
List(a, c, d)
List(b, c, d)

scala> 


We have covered compose, so let's look at the other functions start with C.
def contains (elem: Any): Boolean
Tests whether this list contains a given value as an element.

def containsSlice [B] (that: Seq[B]): Boolean
def containsSlice [B] (that: GenSeq[B]): Boolean
Tests whether this list contains a given sequence as a slice.

def copyToArray (xs: Array[A], start: Int, len: Int): Unit
[use case] Copies elements of this list to an array.
def copyToArray [B >: A] (xs: Array[B], start: Int, len: Int): Unit
Copies elements of this list to an array.
def copyToArray (xs: Array[A]): Unit
[use case] Copies values of this list to an array.
def copyToArray [B >: A] (xs: Array[B]): Unit
Copies values of this list to an array.
def copyToArray (xs: Array[A], start: Int): Unit
[use case] Copies values of this list to an array.
def copyToArray [B >: A] (xs: Array[B], start: Int): Unit
Copies values of this list to an array.

def copyToBuffer [B >: A] (dest: Buffer[B]): Unit
Copies all elements of this list to a buffer.

def corresponds [B] (that: Seq[B])(p: (A, B) ⇒ Boolean): Boolean
def corresponds [B] (that: GenSeq[B])(p: (A, B) ⇒ Boolean): Boolean
Tests whether every element of this list relates to the corresponding element of another sequence by satisfying a test predicate.

def count (p: (A) ⇒ Boolean): Int
Counts the number of elements in the list which satisfy a predicate.
contains is simple. containsSlice needs the sequenced slice as we will see that evenlist return false. There are quite a lot of copyToArray functions. copyToArray is self explanatory name but still the keyword, we usually need to look for reading such functions, is [use case]. In this case, the adequate description is provided for all the functions and we won't be going over the detail but run some code snippet. copyToBuffer needs us to use ListBuffer. The reason that it is not explicitly stated and that a lot of functions description is that the document is generated from the comments from the source code where a lot of other classes also inherit the same functions. If we go look at TraversableOnce source line 219, you will see the description for copyToBuffer. If we also look at all the sub classes, which inherit from TraversableOnce, we will see the reason why the descriptions of the functions are very generic. correponds checks if the other collections have the same elements. count checks the number of element that satisfies the predicate. In our case, it is even test.
scala> val list=List(1,2,3,4,5,6,7,8,9,10)
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.contains(1)
res0: Boolean = true

scala> list.contains("a")
res1: Boolean = false

scala> val taillist=list tail
taillist: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val even:PartialFunction[Int,Int]={case x:Int if x%2==0 =>x}
even: PartialFunction[Int,Int] = <function1>

scala> val evenlist=list collect even
evenlist: List[Int] = List(2, 4, 6, 8, 10)

scala> list containsSlice taillist
res2: Boolean = true

scala> list containsSlice evenlist
res3: Boolean = false

scala> val tailarray = taillist toArray
tailarray: Array[Int] = Array(2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list containsSlice tailarray
res4: Boolean = true

scala> val array=new Array[Int](10)
array: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

scala> list.copyToArray(array,3,5)

scala> array
res6: Array[Int] = Array(0, 0, 0, 1, 2, 3, 4, 5, 0, 0)

scala> list.copyToArray(array)

scala> array
res8: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val arrayAny=new Array[Any](8)
arrayAny: Array[Any] = Array(null, null, null, null, null, null, null, null)

scala> list.copyToArray(arrayAny)

scala> arrayAny
res10: Array[Any] = Array(1, 2, 3, 4, 5, 6, 7, 8)

scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer

scala> val listbuffer=new ListBuffer[Int]()
listbuffer: scala.collection.mutable.ListBuffer[Int] = ListBuffer()

scala> list.copyToBuffer(listbuffer)

scala> listbuffer
res12: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val array=list.toArray
array: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.corresponds(array){(le,ae)=>le==ae}
res13: Boolean = true

scala> list.count{a => a%2==0}
res14: Int = 5
After we learn C, we learn D, right?


Authored by Win Myo Htet