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

O'Reilly logo
Haskell Design Patterns

Book Description

Take your Haskell and functional programming skills to the next level by exploring new idioms and design patterns

About This Book

  • Explore Haskell on a higher level through idioms and patterns

  • Get an in-depth look into the three strongholds of Haskell: higher-order functions, the Type system, and Lazy evaluation

  • Expand your understanding of Haskell and functional programming, one line of executable code at a time

  • Who This Book Is For

    If you’re a Haskell programmer with a firm grasp of the basics and ready to move more deeply into modern idiomatic Haskell programming, then this book is for you.

    What You Will Learn

  • Understand the relationship between the “Gang of Four” OOP Design Patterns and Haskell

  • Try out three ways of Streaming I/O: imperative, Lazy, and Iteratee based

  • Explore the pervasive pattern of Composition: from function composition through to high-level composition with Lenses

  • Synthesize Functor, Applicative, Arrow and Monad in a single conceptual framework

  • Follow the grand arc of Fold and Map on lists all the way to their culmination in Lenses and Generic Programming

  • Get a taste of Type-level programming in Haskell and how this relates to dependently-typed programming

  • Retrace the evolution, one key language extension at a time, of the Haskell Type and Kind systems

  • Place the elements of modern Haskell in a historical framework

  • In Detail

    Design patterns and idioms can widen our perspective by showing us where to look, what to look at, and ultimately how to see what we are looking at. At their best, patterns are a shorthand method of communicating better ways to code (writing less, more maintainable, and more efficient code).

    This book starts with Haskell 98 and through the lens of patterns and idioms investigates the key advances and programming styles that together make "modern Haskell". Your journey begins with the three pillars of Haskell. Then you'll experience the problem with Lazy I/O, together with a solution. You'll also trace the hierarchy formed by Functor, Applicative, Arrow, and Monad. Next you'll explore how Fold and Map are generalized by Foldable and Traversable, which in turn is unified in a broader context by functional Lenses. You'll delve more deeply into the Type system, which will prepare you for an overview of Generic programming. In conclusion you go to the edge of Haskell by investigating the Kind system and how this relates to Dependently-typed programming.

    Style and approach

    Using short pieces of executable code, this guide gradually explores the broad pattern landscape of modern Haskell. Ideas are presented in their historical context and arrived at through intuitive derivations, always with a focus on the problems they solve.

    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 If you purchased this book elsewhere, you can visit and register to have the code file.

    Table of Contents

    1. Haskell Design Patterns
      1. Table of Contents
      2. Haskell Design Patterns
      3. Credits
      4. About the Author
      5. About the Reviewer
        1. Support files, eBooks, discount offers, and more
          1. Why subscribe?
          2. Free access for Packt account holders
      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. Functional Patterns – the Building Blocks
        1. Higher-order functions
          1. Functions as first-class citizens
          2. Composing functions
        2. Currying functions
          1. Currying and composability
          2. Decoupling with currying
        3. Recursion
          1. Non-tail recursion
          2. Tail recursion
          3. Folding abstracts recursion
        4. Types, pattern matching and polymorphism
          1. Algebraic types and pattern matching
            1. Recursive types
          2. Polymorphism
            1. Parametric polymorphism
            2. Ad-hoc polymorphism
              1. Alternation-based ad-hoc polymorphism
              2. Class-based ad-hoc polymorphism
              3. Alternation-based versus class-based
              4. Polymorphic dispatch and the visitor pattern
              5. Unifying parametric and ad-hoc polymorphism
          3. Functions, types, and patterns
            1. The Strategy pattern
            2. The Template pattern
            3. The Iterator pattern
            4. Decoupling behavior and modularizing code
        5. Lazy evaluation
          1. Streams
            1. Modeling change with streams
            2. Lazy evil
        6. Monads
          1. Composing monads and structuring programs
        7. Summary
      9. 2. Patterns for I/O
        1. I/O as a first class citizen
          1. I/O as a functor, applicative, and monad
        2. Imperative I/O
        3. Lazy I/O
          1. The problems with lazy I/O
          2. Resource management with bracket
        4. Iteratee I/O
          1. Iteratee
          2. Enumerator
          3. Generalized iteratees, enumerators, and enumeratees
          4. Iteratee I/O libraries
        5. Comparing the three styles of I/O
        6. Summary
      10. 3. Patterns of Composition
        1. Functor
        2. Applicative functor
        3. Monad
          1. Monad as Functor
          2. Monad as Applicative
          3. Sequencing actions with Monad and Applicative
          4. Monads and the bind chain
          5. Composing with Monads
          6. Monad transformers
            1. IO in Monad stacks
            2. Sequence of stack composition
        4. Arrows
          1. Implementing an Arrow
          2. Arrow operators
          3. Kleisli Arrows and Monad Arrows
          4. Why Arrows?
        5. Summary
      11. 4. Patterns of Folding and Traversing
        1. Folding over lists
          1. Folding with monadic functions
          2. Folding with Monoid
          3. Foldable
        2. Mapping over lists
          1. Traversable
          2. A Traversable Tree
          3. The traversal and the Iterator pattern
        3. Modernizing Haskell 98
        4. Lenses
          1. Deriving Lens
          2. Writing a Lens
          3. Composable getters and setters
          4. Lens Traversal
          5. Lens.Fold
          6. The Lens library
        5. Summary
      12. 5. Patterns of Type Abstraction
        1. Abstracting function types: RankNTypes
        2. Abstracting datatypes
          1. Universal quantification
          2. Existential quantification and abstract datatypes
          3. Phantom types
          4. Generalized algebraic datatypes
            1. The Typecase pattern
            2. Dynamic types
            3. Heterogeneous lists
              1. Using existentials
              2. Using GADTs
        3. Abstracting type-classes
          1. Multiparameter type-classes
          2. Functional dependencies
        4. Summary
      13. 6. Patterns of Generic Programming
        1. Patterns of generic programming
          1. Patterns 1 and 2 – functions
          2. Pattern 3 – polymorphic types and functions
          3. Pattern 4 – type-class polymorphism
          4. Pattern 5 – meta-programming
            1. Derivable type-classes
            2. Generalized newtype deriving
          5. Pattern 6 – type laws
          6. Pattern 7 – datatype generic programming
        2. The sum of products style
          1. The sum of products type representation
          2. Translating between the type and representation
          3. Writing a datatype-generic function
          4. Adding a new datatype
          5. GHC.Generics – a generic deriving mechanism
        3. Origami programming
          1. Tying the recursive knot
          2. Generic map
          3. Generic fold
          4. Generic unfold and fold
          5. Origami design patterns
        4. Scrap your boilerplate
          1. Type-safe cast with Typeable
          2. Type-safe function application
          3. Shallow traversal and the Data type-class
          4. Typeable and data
          5. Scrap your boilerplate in context
        5. Summary
      14. 7. Patterns of Kind Abstraction
        1. Higher-order kinds
        2. Higher-kinded polymorphism
        3. Associated type synonyms
          1. Using functional dependencies
          2. Associated type synonyms
          3. Associated types versus functional dependencies
        4. Type (synonym) families
          1. Data families
        5. Kind polymorphism
          1. The PolyKinds language extension
        6. Type promotion
          1. Promoting types to kinds
        7. Type-level programming
          1. Promoting term-level programs to type-level
          2. Closed type families
          3. The history of type-level programming in Haskell
          4. Type-level and generic programming
        8. Dependently-typed programming
          1. Haskell and dependently-typed programming
        9. Summary
        10. Epilogue
      15. Index