This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Last revision Both sides next revision
sesiuni:scala:lab8 [2016/07/06 12:07]
dciocirlan created
sesiuni:scala:lab8 [2016/07/06 18:54]
ataleanu [Practice]
Line 16: Line 16:
 == Practice == == Practice ==
 +We'll extend an existing well-known type with a few methods, use implicits to sort collections of our own datatypes and finally try to improve equality operations in Scala.
 +  - Define the class ''​RichInteger''​ that takes an Int parameter: <code scala>
 +class RichInteger(val x: Int)</​code>​
 +    * Define the sqrt method on it. It should do the square root of x. Use an implicit conversion from ''​Int''​ to ''​RichInteger''​ to enable this operation on integers.
 +    * Convert the previous code to an implicit class. How does this help you?
 +    * Add an isPrime method to ''​RichInteger''​. It should check whether x is prime or not.
 +    * Add the ''​gcd''​ method to ''​RichInteger''​. It should receive another y parameter of type ''​Int''​ and compute the greatest common divisor of the two.
 +    * Test the new magic methods you just created.
 +  - Define a data type for {{http://​semver.org/​|semantic versioning}}.
 +    * Use a case class and name it ''​Version''​. It should have 3 fields, all integers: ''​major'',​ ''​minor''​ and ''​patch''​.
 +    * Define the ''<''​ operator on the new data type.
 +    * Define a value for a ''​Version''​ ordering. Its type should be ''​Ordering[Version]''<​code scala>
 +val order: Ordering[Version] = ???</​code>​
 +    * Create a list of versions. Try calling the ''​sorted''​ method on it. Does it work?
 +    * Promote the ordering defined earlier to an implicit value. What's the recommended place to put the implicit?
 +  - Define the ''​Eq''​ typeclass to offer support for equality testing.<​code scala>
 +trait Eq[A] {
 +  def ===(l: A, r: A): Boolean
 +  def =!=(l: A, r: A): Boolean
 +    * The two operations should check for equality. Tip - you can use the existing ''​==''​ and ''​!=''​ in the actual implementation.
 +    * Typeclasses usually define additional ''​Ops''​ traits in order to provide an operator like notation to the implementing types. Use the following companion object for Eq in order to enable ''​===''​ and ''​=!=''​ on any type class instance.<​code scala>
 +object Eq {
 +  def apply[A](implicit instance: Eq[A]): Eq[A] = instance
 +  trait Ops[A] {
 +    def typeClassInstance:​ Eq[A]
 +    def self: A
 +    def ===(other: A) = typeClassInstance.===(self,​ other)
 +    def =!=(other: A) = typeClassInstance.=!=(self,​ other)
 +  }
 +  trait ToEqOps {
 +    implicit def toEqOps[A](target:​ A)(implicit instance: Eq[A]) = new Ops[A] {
 +      override val typeClassInstance = instance
 +      override val self              = target
 +    }
 +  }
 +  object ops extends ToEqOps
 +    * Define an instance for ''​Int''​s. Use the ''​Eq''​ object to define it. Compare two integers using the ''​===''​ and ''​=!=''​ methods. Does it work for other types as well (e.g. Strings)?
 +    * Define an universal instance that compares generic types. What's the difference between ''​==''​ vs. ''​===''​ and ''​!=''​ vs ''​=!=''?​
sesiuni/scala/lab8.txt · Last modified: 2016/07/06 18:55 by dciocirlan