Or, let’s face it… copying
Runar Bjarnasson - Introduction to Functional Programming
- Bill Carlson
- Innovation Developer at Cotiviti Labs
- I get paid to write purely functional programs!
Programming with Functions
A function f: A => B
maps any value from one set to exactly one value in another set.
And nothing else
- Totality: A function will return a single value for all values of
A
. - Determinism: Every time you call a function with the same arguments, you will always get the same result.
- Purity: The result of the function is the only effect.
You can replace all occurrences of a function call with the result of that call without changing the program.
val string = "some text"
val s1 = string.reverse
val s2 = string.reverse
val s3 = s1 + s2
val sb = new StringBuilder("some text")
val s1 = sb.reverse
val s2 = sb.reverse
val s3 = s1 append s2
- Console?
- File access?
- Network?
- Exceptions?
Oh, boy… live code…
Empty List: Nil
Non-empty list (cons): A :: List[A]
To build large lists, just add to a smaller list:
val list1 = 2 :: 3 :: 4 :: 5 :: Nil // List(2, 3, 4, 5)
val list2 = 1 :: list1
Some[A]
None
def fold[A](o: Option[A], z: B)(f: A => B): B = o match {
case Some(a) => f(a)
case None => z
}
Left[E]
Right[A]
def fold[E, A](e: Either[E, A], z: E => B, f: A => B): B = e match {
case Left(e) => z(e)
case Right(a) => f(a)
}
- Your program is the data structure
- Your interpreter is the fold
- GoF Interpreter Pattern
Can this be extended?
def ????(i: Int): Int
def inc(i: Int) = i + 1
def timesTwo(i: Int) = i * 2
def abs(i: Int) = if (i < 0) -i else i
???
def ????[A](i: A): A
def identity[A](i: A): A = i
[T]he purpose of abstracting is not to be vague, but to create a new semantic level in which one can be absolutely precise.
– Edsger W. Dijkstra, “The Humble Programmer”
- Console?
- File access?
- Network?
- Exceptions?
sealed trait Console[A]
case class Print(s: String) extends Console[Unit]
case object Read extends Console[Option[String]]
sealed trait File[A]
case class Open(p: Path) extends File[Unit]
case class Write(data: Array[Byte]) extends File[Unit]
case object Read extends File[Array[Byte]]
case object Truncate extends File[Unit]
An algebra is an abstract set of operations
Provides laws which must hold true
Using algebras, combinators, and folds, we simplify (evaluate) the program to a single value.
…maybe a good topic for next time?
Bill Carlson