(Lambda) Functions
Total Page:16
File Type:pdf, Size:1020Kb
Real World Haskell main.title Page iii Monday, May 19, 2008 11:21 AM ?? EDITION Real World TomcatHaskell™ The Definitive Guide Bryan O'Sullivan, JasonJohn Goerzen,Brittain and and Ian Don F. DarwinStewart Beijing • Cambridge • Farnham • Köln • Sebastopol • Taipei • Tokyo Real World Haskell by Bryan O'Sullivan, John Goerzen, and Don Stewart Copyright © 2007, 2008 Bryan O'SullivanJohn GoerzenDon Stewart. All rights reserved. Editor: Mike Loukides Printing History: ISBN: 978---059-65149-83 1220034018 Table of Contents Why functional programming? Why Haskell? .................................... xiii 1. Getting Started ......................................................... 1 Your Haskell environment 1 Getting started with ghci, the interpreter 2 Basic interaction: using ghci as a calculator 3 Command line editing in ghci 9 Lists 9 Strings and characters 11 First steps with types 12 A simple program 15 Exercises 16 2. Types and Functions .................................................... 17 Why care about types? 17 Haskell's type system 17 What to expect from the type system 20 Some common basic types 21 Function application 22 Useful composite data types: lists and tuples 23 Functions over lists and tuples 26 Function types and purity 27 Haskell source files, and writing simple functions 27 Understanding evaluation by example 32 Polymorphism in Haskell 36 The type of a function of more than one argument 38 Exercises 39 Why the fuss over purity? 39 Conclusion 40 3. Defining Types, Streamlining Functions .................................... 41 Defining a new data type 41 v Type synonyms 43 Algebraic data types 44 Pattern matching 50 Record syntax 55 Parameterised types 57 Recursive types 58 Reporting errors 60 Introducing local variables 62 The offside rule and white space in an expression 64 The case expression 67 Common beginner mistakes with patterns 67 Conditional evaluation with guards 68 Exercises 69 4. Functional programming ................................................ 73 Thinking in Haskell 73 A simple command line framework 73 Warming up: portably splitting lines of text 74 Infix functions 78 Working with lists 79 How to think about loops 86 Anonymous (lambda) functions 101 Partial function application and currying 103 As-patterns 106 Code reuse through composition 107 Tips for writing readable code 110 Space leaks and strict evaluation 110 5. Writing a library: working with JSON data ................................. 115 A whirlwind tour of JSON 115 Representing JSON data in Haskell 115 The anatomy of a Haskell module 117 Compiling Haskell source 118 Generating a Haskell program, and importing modules 118 Printing JSON data 119 Type inference is a double-edged sword 120 A more general look at rendering 122 Developing Haskell code without going nuts 123 Pretty printing a string 124 Arrays and objects, and the module header 126 Writing a module header 127 Fleshing out the pretty printing library 128 Creating a package 135 vi | Table of Contents Practical pointers and further reading 138 6. Using Typeclasses ..................................................... 139 The need for typeclasses 139 What are typeclasses? 140 Declaring typeclass instances 143 Important Built-In Typeclasses 143 Automatic Derivation 153 Typeclasses at work: making JSON easier to use 154 Living in an open world 156 How to give a type a new identity 160 JSON typeclasses without overlapping instances 163 The dreaded monomorphism restriction 166 Conclusion 168 7. I/O .................................................................. 169 Classic I/O in Haskell 169 Working With Files and Handles 173 Extended Example: Functional I/O and Temporary Files 179 Lazy I/O 182 The IO Monad 187 Is Haskell Really Imperative? 192 Side Effects with Lazy I/O 192 Buffering 193 Reading Command-Line Arguments 194 Environment Variables 195 8. Efficient file processing, regular expressions, and file name matching .......... 197 Efficient file processing 197 File name matching 201 Regular expressions in Haskell 202 More about regular expressions 204 Translating a glob pattern into a regular expression 206 An important aside: writing lazy functions 209 Making use of our pattern matcher 210 Handling errors through API design 214 Putting our code to work 215 Exercises 216 9. I/O case study: a library for searching the filesystem ......................... 217 The find command 217 Starting simple: recursively listing a directory 217 A naive finding function 219 Table of Contents | vii Predicates: from poverty to riches, while remaining pure 221 Sizing a file safely 223 A domain specific language for predicates 226 Controlling traversal 230 Density, readability, and the learning process 232 Another way of looking at traversal 233 Useful coding guidelines 236 Exercises 238 10. Code case study: parsing a binary data format .............................. 239 Greyscale files 239 Parsing a raw PGM file 240 Getting rid of boilerplate code 242 Implicit state 243 Introducing functors 248 Writing a functor instance for Parse 254 Using functors for parsing 255 Rewriting our PGM parser 256 Future directions 257 Exercises 258 11. Testing and quality assurance ........................................... 259 QuickCheck: type-based testing 259 Testing case study: specifying a pretty printer 263 Measuring test coverage with HPC 269 12. Barcode recognition ................................................... 273 A little bit about barcodes 273 Introducing arrays 274 Encoding an EAN-13 barcode 279 Constraints on our decoder 279 Divide and conquer 280 Turning a colour image into something tractable 281 What have we done to our image? 284 Finding matching digits 286 Life without arrays or hash tables 292 Turning digit soup into an answer 296 Working with row data 299 Pulling it all together 300 A few comments on development style 301 13. Data Structures ....................................................... 303 Association Lists 303 viii | Table of Contents Maps 305 Functions Are Data, Too 307 Extended Example: /etc/passwd 308 Extended example: Numeric Types 311 Taking advantage of functions as data 320 General purpose sequences 326 14. Monads .............................................................. 329 Introduction 329 Revisiting earlier code examples 329 Looking for shared patterns 331 The Monad typeclass 333 And now, a jargon moment 334 Using a new monad: show your work! 335 Mixing pure and monadic code 338 Putting a few misconceptions to rest 340 Building the Logger monad 340 The Maybe monad 341 The list monad 344 Desugaring of do blocks 348 The state monad 350 Monads and functors 357 The monad laws, and good coding style 359 15. Programming with monads ............................................. 363 Golfing practice: association lists 363 Generalised lifting 364 Looking for alternatives 365 Adventures in hiding the plumbing 369 Separating interface from implementation 373 The reader monad 376 A return to automated deriving 378 Hiding the IO monad 379 16. Using Parsec .......................................................... 387 First Steps with Parsec: Simple CSV Parsing 387 The sepBy and endBy Combinators 390 Choices and Errors 391 Extended Example: Full CSV Parser 395 Parsec and MonadPlus 397 Parsing an URL-encoded query string 397 Supplanting regular expressions for casual parsing 399 Parsing without variables 399 Table of Contents | ix Applicative functors for parsing 399 Applicative parsing by example 400 Parsing JSON data 402 Parsing a HTTP request 405 17. Interfacing with C: the FFI .............................................. 409 Foreign language bindings: the basics 410 Regular expressions for Haskell: a binding for PCRE 413 Passing string data between Haskell and C 418 Matching on strings 426 18. Monad transformers ................................................... 433 Motivation: boilerplate avoidance 433 A simple monad transformer example 434 Common patterns in monads and monad transformers 435 Stacking multiple monad transformers 437 Moving down the stack 440 Understanding monad transformers by building one 442 Transformer stacking order is important 445 Putting monads and monad transformers into perspective 446 19. Error handling ........................................................ 451 Error Handling with Data Types 451 Exceptions 458 Exercises 466 Error handling in monads 466 20. Systems Programming in Haskell ........................................ 471 Running External Programs 471 Directory and File Information 472 Program Termination 473 Dates and Times 474 Extended Example: Piping 480 21. Using Databases ....................................................... 495 Overview of HDBC 495 Installing HDBC and Drivers 496 Connecting to Databases 496 Transactions 497 Simple Queries 498 SqlValues 499 Query Parameters 499 Prepared Statements 500 x | Table of Contents Reading Results 501 Database Metadata 504 Error Handling 505 22. Extended Example: Web Client Programming .............................. 507 Basic Types 508 The Database 508 The Parser 512 Downloading 515 Main Program 517 23. GUI Programming with gtk2hs ........................................... 519 Installing gtk2hs 519 Overview of the GTK+ Stack 519 User Interface Design with Glade 520 Event-Driven Programming 522 Initializing the GUI 522 The Add Podcast Window 526 Long-Running Tasks 527 Using Cabal 530 Exercises 531 24. Concurrent and multicore programming .................................. 533 Defining concurrency and parallelism 533 Concurrent programming with threads 534 Simple communication