Functional programming in Scala
Functional Programming in Scala has helped over 30,000 developers discover the power of functional programming. You'll soon see why reviewers have called it "mindblowing"! The book smooths the complexity curve of functional programming, making it simple to understand the basics and in...
Otros Autores: | , , , , |
---|---|
Formato: | Libro electrónico |
Idioma: | Inglés |
Publicado: |
Shelter Island, NY :
Manning Publications Co
[2023]
|
Edición: | Second edition |
Materias: | |
Ver en Biblioteca Universitat Ramon Llull: | https://discovery.url.edu/permalink/34CSUC_URL/1im36ta/alma991009755146406719 |
Tabla de Contenidos:
- Intro
- Praise for the First Edition
- Functional Programming in Scala, Second Edition
- Copyright
- contents
- front matter
- foreword to the first edition
- foreword to the second edition
- preface to the second edition
- acknowledgments
- about this book
- How this book is structured
- Audience
- How to read this book
- Code conventions and downloads
- Setting expectations
- liveBook discussion forum
- about the authors
- Part 1. Introduction to functional programming
- 1 What is functional programming?
- 1.1 Understanding the benefits of functional programming
- 1.1.1 A program with side effects
- 1.1.2 A functional solution: Removing the side effects
- 1.2 Exactly what is a (pure) function?
- 1.3 Referential transparency, purity, and the substitution model
- 1.4 Conclusion
- Summary
- 2 Getting started with functional programming in Scala
- 2.1 Introducing Scala the language
- 2.1.1 Running our program
- 2.2 Objects and namespaces
- 2.3 Higher-order functions: Passing functions to functions
- 2.3.1 A short detour: Writing loops functionally
- 2.3.2 Writing our first higher-order function
- 2.4 Polymorphic functions: Abstracting over types
- 2.4.1 An example of a polymorphic function
- 2.4.2 Calling higher-order functions with anonymous functions
- 2.5 Following types to implementations
- 2.6 Conclusion
- Summary
- 2.7 Exercise answers
- 3 Functional data structures
- 3.1 Defining functional data structures
- 3.2 Pattern matching
- 3.3 Data sharing in functional data structures
- 3.3.1 The efficiency of data sharing
- 3.3.2 Recursion over lists and generalizing to higher-order functions
- 3.3.3 More functions for working with lists
- 3.3.4 Loss of efficiency when assembling list functions from simpler components
- 3.4 Trees
- 3.5 Conclusion
- Summary
- 3.6 Exercise answers.
- 4 Handling errors without exceptions
- 4.1 The good and bad aspects of exceptions
- 4.2 Possible alternatives to exceptions
- 4.3 The Option data type
- 4.3.1 Usage patterns for Option
- 4.3.2 Option composition, lifting, and wrapping exception-oriented APIs
- 4.4 The Either data type
- 4.4.1 Accumulating errors
- 4.4.2 Extracting a Validated type
- 4.5 Conclusion
- Summary
- 4.6 Exercise answers
- 5 Strictness and laziness
- 5.1 Strict and nonstrict functions
- 5.2 Lazy lists: An extended example
- 5.2.1 Memoizing lazy lists and avoiding recomputation
- 5.2.2 Helper functions for inspecting lazy lists
- 5.3 Separating program description from evaluation
- 5.4 Infinite lazy lists and corecursion
- 5.5 Conclusion
- Summary
- 5.6 Exercise answers
- 6 Purely functional state
- 6.1 Generating random numbers using side effects
- 6.2 Purely functional random number generation
- 6.3 Making stateful APIs pure
- 6.4 A better API for state actions
- 6.4.1 Combining state actions
- 6.4.2 Nesting state actions
- 6.5 A general state action data type
- 6.6 Purely functional imperative programming
- 6.7 Conclusion
- Summary
- 6.8 Exercise Answers
- Part 2. Functional design and combinator libraries
- 7 Purely functional parallelism
- 7.1 Choosing data types and functions
- 7.1.1 A data type for parallel computations
- 7.1.2 Combining parallel computations
- 7.1.3 Explicit forking
- 7.2 Picking a representation
- 7.2.1 Refining the API
- 7.3 The algebra of an API
- 7.3.1 The law of mapping
- 7.3.2 The law of forking
- 7.3.3 Breaking the law: A subtle bug
- 7.3.4 A fully non-blocking Par implementation using actors
- 7.4 Refining combinators to their most general form
- 7.5 Conclusion
- Summary
- 7.9 Exercise answers
- 8 Property-based testing
- 8.1 A brief tour of property-based testing.
- 8.1.1 Choosing data types and functions
- 8.1.2 Initial snippets of an API
- 8.1.3 The meaning and API of properties
- 8.1.4 The meaning and API of generators
- 8.1.5 Generators that depend on generated values
- 8.1.6 Refining the Prop data type
- 8.2 Test case minimization
- 8.2.1 Using the library and improving its usability
- 8.2.2 Some simple examples
- 8.2.3 Writing a test suite for parallel computations
- 8.3 Testing higher-order functions and future directions
- 8.4 The laws of generators
- 8.5 Conclusion
- Summary
- 8.6 Exercise answers
- 9 Parser combinators
- 9.1 Designing an algebra first
- 9.2 A possible algebra
- 9.2.1 Slicing and nonempty repetition
- 9.3 Handling context sensitivity
- 9.4 Writing a JSON parser
- 9.4.1 The JSON format
- 9.4.2 A JSON parser
- 9.5 Error reporting
- 9.5.1 A possible design
- 9.5.2 Error nesting
- 9.5.3 Controlling branching and backtracking
- 9.6 Implementing the algebra
- 9.6.1 One possible implementation
- 9.6.2 Sequencing parsers
- 9.6.3 Labeling parsers
- 9.6.4 Failover and backtracking
- 9.6.5 Context-sensitive parsing
- 9.7 Conclusion
- Summary
- 9.8 Exercise answers
- Part 3. Common structures in functional design
- 10 Monoids
- 10.1 What is a monoid?
- 10.2 Folding lists with monoids
- 10.3 Associativity and parallelism
- 10.4 Example: Parallel parsing
- 10.5 Typeclasses
- 10.6 Foldable data structures
- 10.7 Composing monoids
- 10.7.1 Assembling more complex monoids
- 10.7.2 Using composed monoids to fuse traversals
- 10.8 Conclusion
- Summary
- 10.9 Exercise answers
- 11 Monads
- 11.1 Functors: Generalizing the map function
- 11.1.1 Functor laws
- 11.2 Monads: Generalizing the flatMap and unit functions
- 11.2.1 The Monad trait
- 11.3 Monadic combinators
- 11.4 Monad laws
- 11.4.1 The associative law.
- 11.4.2 Proving the associative law for a specific monad
- 11.4.3 The identity laws
- 11.5 Just what is a monad?
- 11.5.1 The identity monad
- 11.5.2 The State monad and partial type application
- 11.6 Conclusion
- Summary
- 11.7 Exercise answers
- 12 Applicative and traversable functors
- 12.1 Generalizing monads
- 12.2 The Applicative trait
- 12.3 The difference between monads and applicative functors
- 12.3.1 The Option applicative versus the Option monad
- 12.3.2 The Parser applicative versus the Parser monad
- 12.4 The advantages of applicative functors
- 12.4.1 Not all applicative functors are monads
- 12.5 The applicative laws
- 12.5.1 Left and right identity
- 12.5.2 Associativity
- 12.5.3 Naturality of product
- 12.6 Traversable functors
- 12.7 Uses of Traverse
- 12.7.1 From monoids to applicative functors
- 12.7.2 Traversals with State
- 12.7.3 Combining traversable structures
- 12.7.4 Traversal fusion
- 12.7.5 Nested traversals
- 12.7.6 Monad composition
- 12.8 Conclusion
- Summary
- 12.9 Exercise answers
- Part 4. Effects and I/O
- 13 External effects and I/O
- 13.1 Factoring effects
- 13.2 A simple IO type
- 13.2.1 Handling input effects
- 13.2.2 Benefits and drawbacks of the simple IO type
- 13.3 Avoiding the StackOverflowError
- 13.3.1 Reifying control flow as data constructors
- 13.3.2 Trampolining: A general solution to stack overflow
- 13.4 A more nuanced I/O type
- 13.4.1 Free monads
- 13.4.2 A monad that supports only console I/O
- 13.4.3 Pure interpreters
- 13.5 Non-blocking and asynchronous I/O
- 13.5.1 Composing free algebras
- 13.6 Capabilities
- 13.7 A general-purpose I/O type
- 13.7.1 The main program at the end of the universe
- 13.8 Why the IO type is insufficient for streaming I/O
- 13.9 Conclusion
- Summary
- 13.10 Exercise answers
- 14 Local effects and mutable state.
- 14.1 Purely functional mutable state
- 14.2 A data type to enforce the scoping of side effects
- 14.2.1 A little language for scoped mutation
- 14.2.2 An algebra of mutable references
- 14.2.3 Running mutable state actions
- 14.2.4 Mutable arrays
- 14.2.5 A purely functional in-place quicksort
- 14.3 Purity is contextual
- 14.3.1 What counts as a side effect?
- 14.4 Conclusion
- Summary
- 14.5 Exercise answers
- 15 Stream processing and incremental I/O
- 15.1 Problems with imperative I/O: An example
- 15.2 Simple stream transformations
- 15.2.1 Creating pulls
- 15.2.2 Composing stream transformations
- 15.2.3 Processing files
- 15.3 Extensible pulls and streams
- 15.3.1 Effectful streaming computations
- 15.3.2 Handling errors
- 15.3.3 Ensuring resource safety
- 15.3.4 Dynamic resource allocation
- 15.4 Applications
- 15.5 Conclusion
- Summary
- 15.6 Exercise answers
- index.