Functional Programming Principles In Scala by Martin Odersky