Skip to content

Instantly share code, notes, and snippets.

@allenaven
Last active August 3, 2017 08:37
Show Gist options
  • Save allenaven/76d1fe6eda99af9d314b648f4303ff39 to your computer and use it in GitHub Desktop.
Save allenaven/76d1fe6eda99af9d314b648f4303ff39 to your computer and use it in GitHub Desktop.
Exercises in Ch.2 in "Functional Programming in Scala" book. Introduces some of the Scala syntax and general FP concepts
// In the Functional Programming paradigm, iteration using an incrementing
// loop variable is verboten (bad news for Python folk!)
def factorial(n: Int): Int = {
// Here I define an "inner function" that is recursive. Scala functions
// can (and are) defined anywhere.
// Notice that the arguments for function "go" are the state for the loop
// but those state values don't touch the outside world--they're entirely
// contained in the inner function. This is a FP thing.
def go(n: Int, acc: Int): Int =
if (n <= 0) acc
else go(n-1, n*acc)
go(n, 1)
}
// Recursively get the nth number in the Fibionacci sequence
def fib(n: Int): Int = {
// Recursively get the nth fibionacci #
def rc(n: Int, a: Int, b: Int, counter: Int): Int =
if (counter >= n) b
else rc(n, b, a + b, counter + 1)
rc(n, 0, 1, 2)
}
// Functional iteration
// Notice return value of function really does nothing, function is really called for its
// side effect of printing the stuff out, so it's not purely "functional"
def loopi(nloops: Int): Int = {
(0 until nloops).foreach( i => println("My iterable now has value: " + i ))
nloops
}
// This version is parallelized, the resulting sequence won't be sequential because of that,
// but the point here is how easy parallelization is in Scala.
def parloopi(nloops: Int): Int = {
(0 until nloops).par.foreach( i => println("My parallel iterable now has value: " + i ))
nloops
}
loopi(8)
parloopi(8)
// Returns:
//My iterable now has value: 0
//My iterable now has value: 1
//My iterable now has value: 2
//My iterable now has value: 3
//My iterable now has value: 4
//My iterable now has value: 5
//My iterable now has value: 6
//My iterable now has value: 7
//My parallel iterable now has value: 7
//My parallel iterable now has value: 6
//My parallel iterable now has value: 1
//My parallel iterable now has value: 2
//My parallel iterable now has value: 4
//My parallel iterable now has value: 3
//My parallel iterable now has value: 0
//My parallel iterable now has value: 5
// Command-line arguments pass through value "args"
//var i = 0
//while (i < args.length) {
// if (i != 0)
// print(" ")
// print(args(i))
// i += 1
//}
// can run @ scalafiddle.io
println("Hello, world!")
def recursive_factorial(n: Int): Int = {
def innerfunc(n: Int, accumulated: Int): Int =
if (n <= 0) accumulated
else innerfunc(n-1, n * accumulated)
// function returns the last line
innerfunc(n, 1)
}
println(recursive_factorial(5))
def occurencesOf[A](elem:A, collection:List[A]): List[Int] = {
for {
// Very declarative syntax: Let Scala worry about the iteration
// process. We just tell Scala what we want (the index of every
// element).
(currentElem, index) <- collection.zipWithIndex
if (currentElem == elem)
} yield index
}
val mylist: List[Int] = List(12, 14, 18, 12, 24, 50)
var oc = occurencesOf(12, mylist)
println(oc)
// Typing: this does NOT work because * isn't an "Any" method
// Can create a value of type "Any" but that value won't have
// access to Int methods even though it contains only Ints
//val al: List[Any] = List(5,7,786)
//al.foreach(i => println(i*i))
// This DOES work because * is an "Int" method
val al: List[Int] = List(5,7,786)
al.foreach(i => println(i*i))
// Ch 2 in book "Functional Programming in Scala"
// In Scala, code has to be in an object ("module") or a class
// The following code snippet declares a "singleton" object: simultaneous
// class declaration and instantiation of its only instance
// The object defines three methods
object MyModule {
// The following is a "pure function": no side effects
def abs(n: Int): Int = // function abs takes integer argument, returns integer
if (n < 0) -n // returns the opposite of n if n is negative
else n
// A private method can only be called by members of MyModule
// This function is also a "pure function"
private def formatAbs(x: Int) = {
val msg = "The absolute value of %d is %d"
msg.format(x, abs(x)) // Replaces two placeholders in previous line
}
// Since this function has side effects (printing to screen), it is often
// called a "procedure" rather than a "function"
// "main" is special--the argument and return types are pre-set. Scala
// looks for "main" when you run the program
// The "Unit" return type tells Scala that it's ok for this function not
// to return anything (usu. a hint that a function has side-effects)
def main(args: Array[String]): Unit = // "Unit" is the same as "Void" in Java (??)
println(formatAbs(-42))
}
// Run with a scala command prompt
// scala> :load MyModule.scala
// scala> MyModule.abs(-372)
// Running the program this way returns:
// res1: Int = 372
// Running the program from the ide returns:
// The absolute value of -42 is 42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment