List head and tail in Scala

package com.vff.lessons

import scala.collection.GenTraversable
import scala.collection.GenTraversableOnce

/**
 * In functional-style Scala, Collections are processed
 * by splitting a list into its head and tail, where
 * head is the first element and tail is all other elements.
 * <p>
 * This is very useful and often used in Pattern Matching.
 *
 */
object ListHeadAndTail extends App {

  // Create our list.
  val list = List(1, 2, 3, 4, 5, 6)

  // Output the contents of head (1st item) and then tail (rest of the items).
  println("list.head = " + list.head)
  println("list.tail = " + list.tail)

  // Simple recursion.
  def display[A](s: Seq[A]): Unit = {
    // Here is our pattern matching:
    s match {
      // case of an empty list
      case Nil => println("End of list")
      /* match the case where list is not empty -  get first item and 
       * recurse with new list containing the rest of the items - by 
       * default scala collection classes will be immutable.
       */
      case head :: tail => println("Got element - " + head); display(tail)
    }
  }
  
  display(list)
}

Output:

list.head = 1
list.tail = List(2, 3, 4, 5, 6)
Got element - 1
Got element - 2
Got element - 3
Got element - 4
Got element - 5
Got element - 6
End of list
Advertisements

Curried functions in Scala

This is a functional programming concept.
The simplest form of the idea is this – imagine a function with 2 parameters, x and y and providing a sister-function to it where one of the parameters is set, this is similar to how the curried functions work. My focus in this example is the syntax.

/**
 * Example of 'curried' method on functions.
 *
 *  Having function f(x:X,y:Y):Z f.curried returns function g(x:X) returning (y:Y) => Z
 */
object CurriedFunction extends App {
  
  /* We will provide a 'charAt' function taking a String and position (Int). */
  val f: (String,Int) => Char = (s,i) => s.charAt(i)

  /* Currying the method - we now create a function g taking just an Int. */
  val g = f.curried("test")

  /* Another form - but h takes 2 parameter lists - both containing one element. */
  val h = f.curried
  
  /* How we call the 2 curried methods. */
  println("Value for test, 1 = " + g(1))
  println("Value for diddle, 1 = " + h("diddle")(1))
}

The real purpose of currying is to do with arity – turning a function with multiple arguments into a series of functions with single arguments, but it involves functions returning other functions…

Call-by-name in Scala

Call-by-name is where a parameter to a function is a function evaluated each time it is used. In this example the function getString is invoked each time it is accessed by the logWaitThenLogAgain method:

import java.util.Date

/**
 * This class demonstrates Call-By-Name behaviour in Scala.
 */
object CallByName extends App {

  /**
   * Note the param of this function:
   * f: => String, instead of f:String
   * This makes the function 'f' a call-by-name parameter 
   * evaluated every time 'f' is accessed.
   */
  def logWaitThenLogAgain(f: => String) = {
    println("[INFO] " + f)
    Thread.sleep(1000) // wait 1 second
    println("[INFO] " + f)
  }

  // Just returns the current date/time as a String
  def getString = new Date().toGMTString()

  // Call our function passing the getString method.
  logWaitThenLogAgain(getString)
}

output:

[INFO] 25 Sep 2013 18:21:26 GMT
[INFO] 25 Sep 2013 18:21:27 GMT

The example demonstrates how Scala passes a method parameter as a function.

Implicit Type Conversion in Scala

package com.vff.lessons

import java.io.File
import java.io.FileInputStream
import javax.swing.JOptionPane

/**
 * This class demonstrates how to make implicitly convert one type T to another U
 * allowing methods taking parameter T also take parameter U
 */
object ImplicitConversion extends App {

  // Automatically allow File arguments to be passed as Strings.
  implicit def stringToFile(name:String): File = new File(name)

  // cheap and cheerful / not-very functional file reading. Lol.
  def readFile(file:File) = {
    val fs = new FileInputStream(file)
    val buffer = new Array[Byte](fs.available)
    fs.read(buffer)
    fs.close()
    println(new String(buffer))
  }
  
  // Pop-up a dialog asking for the filename.
  val name = JOptionPane.showInputDialog("Filename?")
  
  // readFile(File) now takes our String.
  println(readFile(name))
  
}

Implicit type-conversion is very powerful but the implicit keyword is alien to a lot of non-scala developers.