“The Neophyte’s Guide to Scala” by Daniel Westheide

This Scala tutorial, called "The Neophyte’s Guide to Scala" can be considered as an auxiliary resource of #progfun. It is particularly good at getting started with Scala, and to delve a bit deeper with it.

From November 2012 to April 2013, I created and published a blog series called , targeted at aspiring Scala enthusiasts who have already made their first steps with the language and are looking for more detailed explanations.

Enjoy!

Project Euler 03. Largest prime factor with Scala

Problem Definition

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143?

Source: https://projecteuler.net/problem=3

Solution

object Euler03 {

  type Factor = Long
  type Number = Long
  type Factors = List[Factor]

  /* Returns the largest prime factor of the given
   * number.It first computes all the prime factors of the given
   * number and then returns the largest among them.
   */
  def largestPrimeFactor (x: Number): Factor = 
    primeFactors(x).max


  /* Returns the prime factors of the given number x. For instance
   * if the number x equals to 5, it returns List(2,3).
   */
  def primeFactors(x: Number): Factors = {
    val numUpToSqrt = (2L to math.sqrt(x).toLong)
    val divisibleBy = numUpToSqrt.find(x % _ == 0)

    divisibleBy match {
      case None =>  List(x) 
      // x is a prime number and not divisible by any
      case Some(d) => d :: primeFactors(x/d)
    }
  }
}

Scala Notes: Pattern Matching

Pattern matching lets you automatically execute code based on some piece of data. Scala uses pattern matching often, such as when you parse XML or pass messages between threads. Basic syntax of pattern matching is as follow.

    target match { case _ => result } 

Following are the important aspects of pattern matching:

Pattern matching works a bit like a switch statement.

def dochore(chore:String):String = chore match{
    case "A" => "A"
    case "B" => "B"  
    case  _  => "C"
}

A pattern matches a target if it is structurally equivalent to the pattern in question. If multiple pattern matches the target, Scala chooses the first matching case.

List(1,2,3) match { case _ => 42} // => 42
List(1,2,3) match { case h::t => h}    // => 1 
List(1,2,3) match { case h::t => t}     // => List(2,3) 

If none of the patterns matches with the target, MatchError occurs. A MatchError indicates that the none of the cases in a match expression matched the target.

List(1,2,3) match {case Nil => 42}     // => `MatchError` at runtime. 

Next, we outline few concrete examples.

Examples

Example1: Computing Factorial. To compute a factorial in Scala, we specify a condition in a guard for each match statement.

def factorial(n: Int): Int = n match {
    case 0 => 1 
    case x if x>0 => factorial(n-1) *n 
}

Example 2: Computing summation of a given List as an argument. To do this, we need to define a function with signature: def sum(l:List[int]) and implement it as follows.

def sum (list:List[Int]) = {
    def sumAux (xs:List[Int], res:Int):Int = xs match {
      case Nil   => res
      case x::xt => sumAux(xt, res+x) <span class="bullet rounded">1</span>
    }

    sumAux (list, 0)
}

Example 3: Computing Product is taken from Functional Programming in Scala book.

sealed trait List[+A]
case object Nil extends List[Nothing]
case class(head: A, tail:List[A]) extends List[A]

def product(ds: List[Double]): Double = ds match{
    case Nil => 1.0
    case Cons(0,0,_) => 0.0 
    case Cons(x, xs) => x * product(xs)   
}

Gist: Scala Set

In Scala, an instance of Set can be declared as follows.

val s = (1 to 6).toSet

Principle difference between sets and sequences are three:

  • Sets are unordered
val s = (1 to 6).toSet
//> s : scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 3, 4)
  • Sets do not have duplicate elements
s map (_ % 2 ==0)
//> res8: scala.collection.immutable.Set[Boolean] = Set(false, true)
  • The fundamental operation on set is contains.
s contains 5
//> res9: Boolean = true