This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
In functional programming, we ideally want to use pure functions to keep our code simple and modular. By definition a pure | |
function is one that does not have side effects. A method called func with an input type A and output B can be represented as | |
a pure function in Scala in the following manner: | |
*/ | |
def [A,B]func(a: A): B //think A => B or A mapped to B | |
/** | |
The concept of referential transparency applies to any expression which can be replaced with its result without changing the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Functions in Scala can be viewed as first class objects - even values! They can be stored in variables, containers (data structs) | |
and make up function arguments. A function that accepts other functions as parameters is a Higher Order Function. | |
*/ | |
case class Person(name: String, age: Int) | |
val People = List(Person("Bob", 25), Person("Joe", 17), Person("Jim", 22)) | |
/** | |
We can now partition this list of Persons into two separate lists based on each person's age. The partition method accepts |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
In scala, polymorphic functions are the same thing as template functions in C++ or a generic function in other languages: | |
Functions which work over a given type, A. The following functions finds the first occurance of a value in an Array of Type A. | |
Note: We do use Options in the example for safety, please see material on Options for an explanation. | |
*/ | |
def findFirst[A](as: Array[A], p: A => Boolean): Option[Int] = {fin | |
@annotation.tailrec | |
def loop(n: Int): Option[Int] = | |
if (n > as.length) None |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
This example illustrates how to check if an array is sorted based on the given comparison function | |
*/ | |
def isSorted[A](as: Array[A], ordered(A,A) => Boolean): Boolean = { | |
def loop(n: Int): Boolean = | |
if (n+1 > as.length) True | |
else if (!ordered(as(n), as(n+1))) False | |
else loop(n+1) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
This is an example of a higher order function performing a partial application. This following method takes a value and a function | |
of two arguments to return a function of one argument as its result. The name partial implies that the function is being applied | |
to some, but not all of the elements it requires. Think of recipes when looking at type implementations. We can approach this by | |
designing a function literal that first takes an argument of type B. As for a type C in our function literal, there is only one | |
way to get it: f(a,b) yields C. | |
*/ | |
def partial[A,B,C](a: A, f: (A,B) => C): B => C = { | |
(b:B) => f(a,b) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Let's look at currying; a function which converts a function f of two args into a function of one argument that partially applies f | |
*/ | |
def curry[A,B,C](f: (A,B) => C): A => (B => C) = { | |
(a: A) => ((b: B) => f(a,b)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
The following function reverses the affects of a curried function. | |
*/ | |
def uncurry[A,B,C](f: A => B => C): (A,B) => C = { | |
(a,b) => f(a)(b) | |
} |