O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

F# 4.0 Design Patterns

Book Description

Learn how to apply functional F# design patterns to a huge range of programming challenges, and discover a smart route to building better applications

About This Book

  • This book provides a path if you are coming from imperative and object-oriented paradigms
  • It will take you to an intermediate level of functional programming in very practical manner to write enterprise-quality idiomatic F# code
  • Tackle complex computing problems with simple code by fully embracing the functional-first F# paradigm
  • Packed full of practical coding examples to help you master F# programming and author optimal code

Who This Book Is For

This book is for .NET developers, web programmers, C# developers, and F# developers. So, if you have basic experience in F# programming and developing performance-critical applications, then this book is for you.

What You Will Learn

  • Acquire the practical knowledge to use the main functional design patterns
  • Realign some imperative and object-oriented principles under the functional approach
  • Develop your confidence in building and combining first-order and higher-order functions
  • Learn to use core language pattern matching effectively
  • Make use of native F# algebraic data types in place of custom-built classes
  • Recognize and measure the difference in resource consumption between sequences and materialized data collections
  • Navigate and use F# Core libraries with ease by seeing patterns behind specific library functions
  • Master writing generic polymorphic code

In Detail

Following design patterns is a well-known approach to writing better programs that captures and reuses high-level abstractions that are common in many applications. This book will encourage you to develop an idiomatic F# coding skillset by fully embracing the functional-first F# paradigm. It will also help you harness this powerful instrument to write succinct, bug-free, and cross-platform code.

F# 4.0 Design Patterns will start off by helping you develop a functional way of thinking. We will show you how beneficial the functional-first paradigm is and how to use it to get the optimum results. The book will help you acquire the practical knowledge of the main functional design patterns, the relationship of which with the traditional Gang of Four set is not straightforward.

We will take you through pattern matching, immutable data types, and sequences in F#. We will also uncover advanced functional patterns, look at polymorphic functions, typical data crunching techniques, adjusting code through augmentation, and generalization. Lastly, we will take a look at the advanced techniques to equip you with everything you need to write flawless code.

Style and approach

This book will teach you how to write F# code in an idiomatic functional-first manner, thereby improving the productivity of F# programmers. This book is ideal for an F# programmer who wants using F# in functional-first way.

Downloading the example code for this book. You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the code file.

Table of Contents

  1. F# 4.0 Design Patterns
    1. F# 4.0 Design Patterns
    2. Credits
    3. About the Author
    4. Acknowledgements
    5. About the Reviewer
    6. www.PacktPub.com
      1. Why subscribe?
    7. Preface
      1. What this book covers
      2. What you need for this book
      3. Who this book is for
      4. Conventions
      5. Reader feedback
      6. Customer support
        1. Downloading the example code
        2. Errata
        3. Piracy
        4. Questions
    8. 1. Begin Thinking Functionally
      1. Relationship between F# and programming paradigms
      2. A sample problem to solve
        1. An imperative monolithic solution
        2. An object-oriented solution
        3. A functional solution
      3. Immutability of participating data entities
      4. Thinking in verbs rather than nouns
      5. "What" prevailing over "how"
      6. Generalization over specialization
      7. Minimizing moving parts over hiding them
      8. Reduction to known parts over producing custom parts
      9. Lazy over eager data collections
      10. Summary
    9. 2. Dissecting F# Origins and Design
      1. The evolvement of F#
        1. Predecessors
        2. F# Version 1
        3. F# Version 1.1
        4. F# Version 2
        5. F# Version 3
        6. F# Version 4
      2. Predecessor inherited language features
        1. F# functions are first-class entities
        2. Functions are free of side effects
        3. Functions can be curried and partially evaluated
        4. Functions may be anonymous
        5. Functions may be recursive
        6. Functions may raise exceptions
        7. Functions may reference external values
        8. F# is a statically typed language
        9. F# type inference provides type generalization
        10. F# supports parametric polymorphism
        11. F# inherits the variety of aggregate data structures from ML
        12. F# supports pattern matching
        13. F# supports data references
        14. Functions are non-recursive by default
        15. Modules
      3. .NET-imposed language features
        1. F# adheres to .NET Common Language Infrastructure
        2. F# has nominal type system
        3. F# fully embraces .NET object orientation
        4. F# requires calling the method of an explicit interface
        5. Object expressions
        6. Reflection
        7. Extending classes and modules
        8. Enumerations
        9. Structures
        10. Events
        11. Nullable types
        12. Interoperation with the managed code
        13. Interoperation with unmanaged code
      4. Intrinsic F# language features
        1. Indentation-aware syntax
        2. Units of measure
        3. Overloaded operators
        4. Inline Functions
        5. Type constraints and statically resolved type parameters
        6. Active Patterns
        7. Computation Expressions
        8. Query Expressions
        9. Asynchronous workflows
        10. Meta-programming
        11. Type providers
      5. Summary
    10. 3. Basic Functions
      1. The notion of function in F#
        1. The function definition
        2. The function type signature
        3. Pure functions
      2. Function parameters and arguments
        1. The tuples preview
        2. Special type unit
        3. Currying and partial function application
        4. The number and the type of function parameters and return values
      3. Higher-order functions
        1. Anonymous functions
        2. Functions as arguments
        3. Functions as return values
        4. Functions as data type constituents
        5. Functions are interfaces
      4. Closures
        1. Mutable values
        2. Reference cells
      5. Type inference
      6. Recursive function basics
      7. Operators as functions
      8. Function composition
        1. Combinators
          1. The id combinator
          2. Forward pipe |>
          3. Backward pipe <|
          4. Forward composition >>
          5. Backward composition 
      9. Summary
    11. 4. Basic Pattern Matching
      1. An explicit form of pattern matching with match construction
      2. Matching literals
      3. Wildcard matching
      4. Arranging matching rules
      5. Named patterns
      6. The as pattern
      7. Grouping patterns
      8. Guards
      9. The alternative syntax for anonymous function performing matching
      10. Summary
    12. 5. Algebraic Data Types
      1. Combining data with algebraic data types
      2. Product algebraic data types
        1. Tuples
          1. Tuple composition
          2. Tuple equality and comparison
          3. Tuple decomposition with pattern matching
          4. Tuple augmentation
        2. Records
          1. Record composition
          2. Record equality and comparison
          3. Record decomposition with pattern matching
          4. Record augmentation
      3. Sum algebraic data types
        1. Discriminated unions
          1. Discriminated union composition
            1. The empty constructor case
            2. The single constructor case
          2. Discriminated union equality and comparison
          3. Discriminated union decomposition with pattern matching
          4. Discriminated union augmentation
      4. Summary
    13. 6. Sequences - The Core of Data Processing Patterns
      1. Basic sequence transformations
        1. The aggregation pattern
        2. The generation pattern
        3. The wrapping and type conversion pattern
        4. The application pattern
        5. The recombination pattern
        6. The filtering pattern
        7. The mapping pattern
      2. The sequence: Duality of data and calculation
        1. Sequence as a lazy data collection
        2. Sequence as a calculation
        3. Sequence as an enumerator interface wrapper
          1. Step 1 - The custom enumerator implementation
          2. Step 2 - The custom enumerator factory
          3. Step 3 - The custom sequence factory
      3. Sequence of an indefinite length as a design pattern
        1. Generating the F# sequences
          1. Sequence comprehensions
            1. Ranges
            2. Maps
            3. Arbitrary sequence expressions
          2. Library functions generating sequences
            1. Seq.init
            2. Seq.initInfinite
            3. Seq.unfold
      4. Sequence and the code performance
        1. Sequence caching
        2. The fusion of sequence transformations
      5. Summary
    14. 7. Advanced Techniques: Functions Revisited
      1. A deep dive into recursion
        1. Tail recursion
        2. Mutual recursion
      2. Folding
      3. Memoization
      4. Lazy evaluation
      5. Continuation passing style
      6. Active patterns
        1. Type transformations with active patterns
        2. Data partitioning with active patterns
        3. Data categorization with active patterns
      7. Summary
    15. 8. Data Crunching – Data Transformation Patterns
      1. Core data transformation libraries in F# 4.0
      2. Data transformation patterns
        1. The generation pattern
          1. Generating an empty collection
          2. Generating a single element collection
          3. Generating a collection of a known size
            1. Generating a collection of a known size - all elements of the same value
            2. Generating a collection of a known size - elements may have different values
          4. Generating a collection of an unknown size
          5. Generating a collection of an infinite size
        2. The aggregation pattern
          1. Generic aggregation
          2. Direct aggregation
          3. Projected aggregation
          4. Counting aggregation
        3. The wrapping and type conversion pattern
          1. The collection wrapping pattern
          2. The type conversion pattern
        4. The selection pattern
          1. The position-based selection pattern
            1. Single element selection
            2. The element group selection
        5. The searching pattern
        6. The partitioning pattern
        7. The reordering pattern
        8. The testing pattern
        9. The iterating pattern
        10. The mapping pattern
        11. The folding pattern
        12. The merge/split pattern
      3. Summary
    16. 9. More Data Crunching
      1. Data querying
        1. F# and LINQ before query expressions
        2. Introducing F# query expressions
        3. Query operators
        4. The role of a LINQ provider
        5. External data querying via IEnumerable<'T>
        6. External data querying via IQuerable<'T>
        7. Composable queries
      2. Data parsing
        1. The use case - LaserShip invoicing
        2. Approaching the parsing task
        3. LaserShip parser implementation
      3. Summary
    17. 10. Type Augmentation and Generic Computations
      1. Code generalization
        1. Statically resolved type parameters
        2. Function inlining
        3. Static constraints
        4. Explicit or inferred constraining?
        5. Inlining scope
        6. Inline optimizations
        7. Writing generic code
      2. Type augmentation
        1. Augment by removing
        2. Augment by adding
      3. Summary
    18. 11. F# Expert Techniques
      1. A note on custom computation expressions
      2. Exploring type providers
        1. The feature review
        2. The demo problem
        3. The demo solution
      3. Exploring concurrent computations
        1. The feature review
        2. The demo problem
        3. The demo solution
      4. Exploring reactive computations
        1. The feature review
        2. The demo problem
        3. The demo solution
      5. Exploring quotations and metaprogramming
        1. The feature review
        2. The demo problem
        3. The demo solution
      6. Summary
    19. 12. F# and OOP Principles/Design Patterns
      1. Morphing SOLID principles
        1. Single Responsibility Principle
        2. Open/Closed Principle
        3. Liskov Substitution Principle
        4. Interface Segregation Principle
        5. Dependency Inversion Principle
      2. Diminishing patterns
        1. The Command design pattern
        2. The Template design pattern
        3. The Strategy pattern
      3. Summary
    20. 13. Troubleshooting Functional Code
      1. Why idiomatic F# admits less defects
        1. Reduced bug rate
        2. Prevalence of F# compile-time errors over run-time bugs
      2. Using REPL and the explorative programming style
      3. Addressing some compile-time problems
        1. The if-then return value
        2. Value restriction
          1. Imperfect pattern matching
      4. Addressing run-time problems
      5. Summary