Real World Haskell. Code You Can Believe In - Helion
ISBN: 978-05-965-5430-9
stron: 714, Format: ebook
Data wydania: 2008-11-15
Księgarnia: Helion
Cena książki: 152,15 zł (poprzednio: 176,92 zł)
Oszczędzasz: 14% (-24,77 zł)
This easy-to-use, fast-moving tutorial introduces you to functional programming with Haskell. You'll learn how to use Haskell in a variety of practical ways, from short scripts to large and demanding applications. Real World Haskell takes you through the basics of functional programming at a brisk pace, and then helps you increase your understanding of Haskell in real-world issues like I/O, performance, dealing with data, concurrency, and more as you move through each chapter.
With this book, you will:
- Understand the differences between procedural and functional programming
- Learn the features of Haskell, and how to use it to develop useful programs
- Interact with filesystems, databases, and network services
- Write solid code with automated tests, code coverage, and error handling
- Harness the power of multicore systems via concurrent and parallel programming
You'll find plenty of hands-on exercises, along with examples of real Haskell programs that you can modify, compile, and run. Whether or not you've used a functional language before, if you want to understand why Haskell is coming into its own as a practical language in so many major organizations, Real World Haskell is the best place to start.
Osoby które kupowały "Real World Haskell. Code You Can Believe In", wybierały także:
- Superinteligencja. Scenariusze, strategie, zagro 66,67 zł, (14,00 zł -79%)
- Poradnik design thinking - czyli jak wykorzysta 48,28 zł, (14,00 zł -71%)
- Kosymulacja. Elastyczne projektowanie i symulacja wielodomenowa 38,39 zł, (11,90 zł -69%)
- F# 4.0 dla zaawansowanych. Wydanie IV 96,45 zł, (29,90 zł -69%)
- Systemy reaktywne. Wzorce projektowe i ich stosowanie 65,31 zł, (20,90 zł -68%)
Spis treści
Real World Haskell. Code You Can Believe In eBook -- spis treści
- Real World Haskell
- Dedication
- A Note Regarding Supplemental Files
- Preface
- Have We Got a Deal for You!
- Novelty
- Power
- Enjoyment
- What to Expect from This Book
- A Little Bit About You
- What to Expect from Haskell
- Compared to Traditional Static Languages
- Compared to Modern Dynamic Languages
- Haskell in Industry and Open Source
- Compilation, Debugging, and Performance Analysis
- Bundled and Third-Party Libraries
- A Brief Sketch of Haskells History
- Prehistory
- Early Antiquity
- The Modern Era
- Helpful Resources
- Reference Material
- Applications and Libraries
- The Haskell Community
- Conventions Used in This Book
- Using Code Examples
- Safari Books Online
- How to Contact Us
- Acknowledgments
- Bryan
- John
- Don
- Thank You to Our Reviewers
- Have We Got a Deal for You!
- 1. Getting Started
- Your Haskell Environment
- Getting Started with ghci, the Interpreter
- Basic Interaction: Using ghci as a Calculator
- Simple Arithmetic
- An Arithmetic Quirk: Writing Negative Numbers
- Boolean Logic, Operators, and Value Comparisons
- Operator Precedence and Associativity
- Undefined Values, and Introducing Variables
- Dealing with Precedence and Associativity Rules
- Command-Line Editing in ghci
- Lists
- Operators on Lists
- Strings and Characters
- First Steps with Types
- A Simple Program
- 2. Types and Functions
- Why Care About Types?
- Haskells Type System
- Strong Types
- Static Types
- Type Inference
- What to Expect from the Type System
- Some Common Basic Types
- Function Application
- Useful Composite Data Types: Lists and Tuples
- Functions over Lists and Tuples
- Passing an Expression to a Function
- Function Types and Purity
- Haskell Source Files, and Writing Simple Functions
- Just What Is a Variable, Anyway?
- Conditional Evaluation
- Understanding Evaluation by Example
- Lazy Evaluation
- A More Involved Example
- Recursion
- Ending the Recursion
- Returning from the Recursion
- What Have We Learned?
- Polymorphism in Haskell
- Reasoning About Polymorphic Functions
- Further Reading
- The Type of a Function of More Than One Argument
- Why the Fuss over Purity?
- Conclusion
- 3. Defining Types, Streamlining Functions
- Defining a New Data Type
- Naming Types and Values
- Type Synonyms
- Algebraic Data Types
- Tuples, Algebraic Data Types, and When to Use Each
- Analogues to Algebraic Data Types in Other Languages
- The structure
- The enumeration
- The discriminated union
- Pattern Matching
- Construction and Deconstruction
- Further Adventures
- Variable Naming in Patterns
- The Wild Card Pattern
- Exhaustive Patterns and Wild Cards
- Record Syntax
- Parameterized Types
- Recursive Types
- Reporting Errors
- A More Controlled Approach
- Introducing Local Variables
- Shadowing
- The where Clause
- Local Functions, Global Variables
- The Offside Rule and Whitespace in an Expression
- A Note About Tabs Versus Spaces
- The Offside Rule Is Not Mandatory
- The case Expression
- Common Beginner Mistakes with Patterns
- Incorrectly Matching Against a Variable
- Incorrectly Trying to Compare for Equality
- Conditional Evaluation with Guards
- Defining a New Data Type
- 4. Functional Programming
- Thinking in Haskell
- A Simple Command-Line Framework
- Warming Up: Portably Splitting Lines of Text
- A Line-Ending Conversion Program
- Infix Functions
- Working with Lists
- Basic List Manipulation
- Safely and Sanely Working with Crashy Functions
- Partial and Total Functions
- More Simple List Manipulations
- Working with Sublists
- Searching Lists
- Working with Several Lists at Once
- Special String-Handling Functions
- How to Think About Loops
- Explicit Recursion
- Transforming Every Piece of Input
- Mapping over a List
- Selecting Pieces of Input
- Computing One Answer over a Collection
- The Left Fold
- Why Use Folds, Maps, and Filters?
- Folding from the Right
- Left Folds, Laziness, and Space Leaks
- Further Reading
- Anonymous (lambda) Functions
- Partial Function Application and Currying
- Sections
- As-patterns
- Code Reuse Through Composition
- Use Your Head Wisely
- Tips for Writing Readable Code
- Space Leaks and Strict Evaluation
- Avoiding Space Leaks with seq
- Learning to Use seq
- 5. Writing a Library: Working with JSON Data
- A Whirlwind Tour of JSON
- Representing JSON Data in Haskell
- The Anatomy of a Haskell Module
- Compiling Haskell Source
- Generating a Haskell Program and Importing Modules
- Printing JSON Data
- Type Inference Is a Double-Edged Sword
- A More General Look at Rendering
- Developing Haskell Code Without Going Nuts
- Pretty Printing a String
- Arrays and Objects, and the Module Header
- Writing a Module Header
- Fleshing Out the Pretty-Printing Library
- Compact Rendering
- True Pretty Printing
- Following the Pretty Printer
- Creating a Package
- Writing a Package Description
- GHCs Package Manager
- Setting Up, Building, and Installing
- Practical Pointers and Further Reading
- 6. Using Typeclasses
- The Need for Typeclasses
- What Are Typeclasses?
- Declaring Typeclass Instances
- Important Built-in Typeclasses
- Show
- Read
- Serialization with read and show
- Numeric Types
- Equality, Ordering, and Comparisons
- Automatic Derivation
- Typeclasses at Work: Making JSON Easier to Use
- More Helpful Errors
- Making an Instance with a Type Synonym
- Living in an Open World
- When Do Overlapping Instances Cause Problems?
- Relaxing Some Restrictions on Typeclasses
- How Does Show Work for Strings?
- How to Give a Type a New Identity
- Differences Between Data and Newtype Declarations
- Summary: The Three Ways of Naming Types
- JSON Typeclasses Without Overlapping Instances
- The Dreaded Monomorphism Restriction
- Conclusion
- 7. I/O
- Classic I/O in Haskell
- Pure Versus I/O
- Why Purity Matters
- Working with Files and Handles
- More on openFile
- Closing Handles
- Seek and Tell
- Standard Input, Output, and Error
- Deleting and Renaming Files
- Temporary Files
- Extended Example: Functional I/O and Temporary Files
- Lazy I/O
- hGetContents
- readFile and writeFile
- A Word on Lazy Output
- interact
- Filters with interact
- The IO Monad
- Actions
- Sequencing
- The True Nature of Return
- Is Haskell Really Imperative?
- Side Effects with Lazy I/O
- Buffering
- Buffering Modes
- Flushing The Buffer
- Reading Command-Line Arguments
- Environment Variables
- Classic I/O in Haskell
- 8. Efficient File Processing, Regular Expressions, and Filename Matching
- Efficient File Processing
- Binary I/O and Qualified Imports
- Text I/O
- Filename Matching
- Regular Expressions in Haskell
- The Many Types of Result
- More About Regular Expressions
- Mixing and Matching String Types
- Other Things You Should Know
- Translating a glob Pattern into a Regular Expression
- An important Aside: Writing Lazy Functions
- Making Use of Our Pattern Matcher
- Handling Errors Through API Design
- Putting Our Code to Work
- Efficient File Processing
- 9. I/O Case Study: A Library for Searching the Filesystem
- The find Command
- Starting Simple: Recursively Listing a Directory
- Revisiting Anonymous and Named Functions
- Why Provide Both mapM and forM?
- A Naive Finding Function
- Predicates: From Poverty to Riches, While Remaining Pure
- Sizing a File Safely
- The Acquire-Use-Release Cycle
- A Domain-Specific Language for Predicates
- Avoiding Boilerplate with Lifting
- Gluing Predicates Together
- Defining and Using New Operators
- Controlling Traversal
- Density, Readability, and the Learning Process
- Another Way of Looking at Traversal
- Useful Coding Guidelines
- Common Layout Styles
- 10. Code Case Study: Parsing a Binary Data Format
- Grayscale Files
- Parsing a Raw PGM File
- Getting Rid of Boilerplate Code
- Implicit State
- The Identity Parser
- Record Syntax, Updates, and Pattern Matching
- A More Interesting Parser
- Obtaining and Modifying the Parse State
- Reporting Parse Errors
- Chaining Parsers Together
- Introducing Functors
- Constraints on Type Definitions Are Bad
- Infix Use of fmap
- Flexible Instances
- Thinking More About Functors
- Writing a Functor Instance for Parse
- Using Functors for Parsing
- Rewriting Our PGM Parser
- Future Directions
- 11. Testing and Quality Assurance
- QuickCheck: Type-Based Testing
- Testing for Properties
- Testing Against a Model
- Testing Case Study: Specifying a Pretty Printer
- Generating Test Data
- Testing Document Construction
- Using Lists as a Model
- Putting It All Together
- Measuring Test Coverage with HPC
- QuickCheck: Type-Based Testing
- 12. Barcode Recognition
- A Little Bit About Barcodes
- EAN-13 Encoding
- Introducing Arrays
- Arrays and Laziness
- Folding over Arrays
- Modifying Array Elements
- Encoding an EAN-13 Barcode
- Constraints on Our Decoder
- Divide and Conquer
- Turning a Color Image into Something Tractable
- Parsing a Color Image
- Grayscale Conversion
- Grayscale to Binary and Type Safety
- What Have We Done to Our Image?
- Finding Matching Digits
- Run Length Encoding
- Scaling Run Lengths, and Finding Approximate Matches
- List Comprehensions
- Remembering a Matchs Parity
- Another kind of laziness, of the keyboarding variety
- Chunking a List
- Generating a List of Candidate Digits
- Life Without Arrays or Hash Tables
- A Forest of Solutions
- A Brief Introduction to Maps
- Type constraints
- Partial application awkwardness
- Getting started with the API
- Further Reading
- Turning Digit Soup into an Answer
- Solving for Check Digits in Parallel
- Completing the Solution Map with the First Digit
- Finding the Correct Sequence
- Working with Row Data
- Pulling It All Together
- A Few Comments on Development Style
- A Little Bit About Barcodes
- 13. Data Structures
- Association Lists
- Maps
- Functions Are Data, Too
- Extended Example: /etc/passwd
- Extended Example: Numeric Types
- First Steps
- Completed Code
- Taking Advantage of Functions as Data
- Turning Difference Lists into a Proper Library
- Lists, Difference Lists, and Monoids
- General-Purpose Sequences
- 14. Monads
- Revisiting Earlier Code Examples
- Maybe Chaining
- Implicit State
- Looking for Shared Patterns
- The Monad Typeclass
- And Now, a Jargon Moment
- Using a New Monad: Show Your Work!
- Information Hiding
- Controlled Escape
- Leaving a Trace
- Using the Logger Monad
- Mixing Pure and Monadic Code
- Putting a Few Misconceptions to Rest
- Building the Logger Monad
- Sequential Logging, Not Sequential Evaluation
- The Writer Monad
- The Maybe Monad
- Executing the Maybe Monad
- Maybe at Work, and Good API Design
- The List Monad
- Understanding the List Monad
- Putting the List Monad to Work
- Desugaring of do Blocks
- Monads as a Programmable Semicolon
- Why Go Sugar-Free?
- The State Monad
- Almost a State Monad
- Reading and Modifying the State
- Will the Real State Monad Please Stand Up?
- Using the State Monad: Generating Random Values
- A First Attempt at Purity
- Random Values in the State Monad
- Running the State Monad
- What About a Bit More State?
- Monads and Functors
- Another Way of Looking at Monads
- The Monad Laws and Good Coding Style
- Revisiting Earlier Code Examples
- 15. Programming with Monads
- Golfing Practice: Association Lists
- Generalized Lifting
- Looking for Alternatives
- The Name mplus Does Not Imply Addition
- Rules for Working with MonadPlus
- Failing Safely with MonadPlus
- Adventures in Hiding the Plumbing
- Supplying Random Numbers
- Another Round of Golf
- Separating Interface from Implementation
- Multiparameter Typeclasses
- Functional Dependencies
- Rounding Out Our Module
- Programming to a Monads Interface
- The Reader Monad
- A Return to Automated Deriving
- Hiding the IO Monad
- Using a newtype
- Designing for Unexpected Uses
- Using Typeclasses
- Isolation and Testing
- The Writer Monad and Lists
- Arbitrary I/O Revisited
- 16. Using Parsec
- First Steps with Parsec: Simple CSV Parsing
- The sepBy and endBy Combinators
- Choices and Errors
- Lookahead
- Error Handling
- Extended Example: Full CSV Parser
- Parsec and MonadPlus
- Parsing a URL-Encoded Query String
- Supplanting Regular Expressions for Casual Parsing
- Parsing Without Variables
- Applicative Functors for Parsing
- Applicative Parsing by Example
- Parsing JSON Data
- Parsing a HTTP Request
- Backtracking and Its Discontents
- Parsing Headers
- 17. Interfacing with C: The FFI
- Foreign Language Bindings: The Basics
- Be Careful of Side Effects
- A High-Level Wrapper
- Regular Expressions for Haskell: A Binding for PCRE
- Simple Tasks: Using the C Preprocessor
- Binding Haskell to C with hsc2hs
- Adding Type Safety to PCRE
- Binding to Constants
- Automating the Binding
- Passing String Data Between Haskell and C
- Typed Pointers
- Memory Management: Let the Garbage Collector Do the Work
- A High-Level Interface: Marshaling Data
- Marshaling ByteStrings
- Allocating Local C Data: The Storable Class
- Putting It All Together
- Matching on Strings
- Extracting Information About the Pattern
- Pattern Matching with Substrings
- The Real Deal: Compiling and Matching Regular Expressions
- Foreign Language Bindings: The Basics
- 18. Monad Transformers
- Motivation: Boilerplate Avoidance
- A Simple Monad Transformer Example
- Common Patterns in Monads and Monad Transformers
- Stacking Multiple Monad Transformers
- Hiding Our Work
- Moving Down the Stack
- When Explicit Lifting Is Necessary
- Understanding Monad Transformers by Building One
- Creating a Monad Transformer
- More Typeclass Instances
- Replacing the Parse Type with a Monad Stack
- Transformer Stacking Order Is Important
- Putting Monads and Monad Transformers into Perspective
- Interference with Pure Code
- Overdetermined Ordering
- Runtime Overhead
- Unwieldy Interfaces
- Pulling It All Together
- 19. Error Handling
- Error Handling with Data Types
- Use of Maybe
- Loss and preservation of laziness
- Usage of the Maybe monad
- Use of Either
- Custom data types for errors
- Monadic use of Either
- Use of Maybe
- Exceptions
- First Steps with Exceptions
- Laziness and Exception Handling
- Using handle
- Selective Handling of Exceptions
- I/O Exceptions
- Throwing Exceptions
- Dynamic Exceptions
- Error Handling in Monads
- A Tiny Parsing Framework
- Error Handling with Data Types
- 20. Systems Programming in Haskell
- Running External Programs
- Directory and File Information
- Program Termination
- Dates and Times
- ClockTime and CalendarTime
- Using ClockTime
- Using CalendarTime
- TimeDiff for ClockTime
- File Modification Times
- ClockTime and CalendarTime
- Extended Example: Piping
- Using Pipes for Redirection
- Better Piping
- Final Words on Pipes
- 21. Using Databases
- Overview of HDBC
- Installing HDBC and Drivers
- Connecting to Databases
- Transactions
- Simple Queries
- SqlValue
- Query Parameters
- Prepared Statements
- Reading Results
- Reading with Statements
- Lazy Reading
- Database Metadata
- Error Handling
- 22. Extended Example: Web Client Programming
- Basic Types
- The Database
- The Parser
- Downloading
- Main Program
- 23. GUI Programming with gtk2hs
- Installing gtk2hs
- Overview of the GTK+ Stack
- User Interface Design with Glade
- Glade Concepts
- Event-Driven Programming
- Initializing the GUI
- The Add Podcast Window
- Long-Running Tasks
- Using Cabal
- 24. Concurrent and Multicore Programming
- Defining Concurrency and Parallelism
- Concurrent Programming with Threads
- Threads Are Nondeterministic
- Hiding Latency
- Simple Communication Between Threads
- The Main Thread and Waiting for Other Threads
- Safely Modifying an MVar
- Safe Resource Management: A Good Idea, and Easy Besides
- Finding the Status of a Thread
- Writing Tighter Code
- Communicating over Channels
- Useful Things to Know About
- MVar and Chan Are Nonstrict
- Chan Is Unbounded
- Shared-State Concurrency Is Still Hard
- Deadlock
- Starvation
- Is There Any Hope?
- Using Multiple Cores with GHC
- Runtime Options
- Finding the Number of Available Cores from Haskell
- Choosing the Right Runtime
- Parallel Programming in Haskell
- Normal Form and Head Normal Form
- Sequential Sorting
- Transforming Our Code into Parallel Code
- Knowing What to Evaluate in Parallel
- What Promises Does par Make?
- Running Our Code and Measuring Performance
- Tuning for Performance
- Parallel Strategies and MapReduce
- Separating Algorithm from Evaluation
- Separating Algorithm from Strategy
- Writing a Simple MapReduce Definition
- MapReduce and Strategies
- Sizing Work Appropriately
- Mitigating the risks of lazy I/O
- Efficiently Finding Line-Aligned Chunks
- Counting Lines
- Finding the Most Popular URLs
- Conclusions
- 25. Profiling and Optimization
- Profiling Haskell Programs
- Collecting Runtime Statistics
- Time Profiling
- Space Profiling
- Controlling Evaluation
- Strictness and Tail Recursion
- Adding Strictness
- Normal form reduction
- Bang patterns
- Strict data types
- Understanding Core
- Advanced Techniques: Fusion
- Tuning the Generated Assembly
- Conclusions
- Profiling Haskell Programs
- 26. Advanced Library Design: Building a Bloom Filter
- Introducing the Bloom Filter
- Use Cases and Package Layout
- Basic Design
- Unboxing, Lifting, and Bottom
- The ST Monad
- Designing an API for Qualified Import
- Creating a Mutable Bloom Filter
- The Immutable API
- Creating a Friendly Interface
- Re-Exporting Names for Convenience
- Hashing Values
- Turning Two Hashes into Many
- Implementing the Easy Creation Function
- Creating a Cabal Package
- Dealing with Different Build Setups
- Compilation Options and Interfacing to C
- Testing with QuickCheck
- Polymorphic Testing
- Writing Arbitrary Instances for ByteStrings
- Are Suggested Sizes Correct?
- Performance Analysis and Tuning
- Profile-Driven Performance Tuning
- 27. Sockets and Syslog
- Basic Networking
- Communicating with UDP
- UDP Client Example: syslog
- UDP Syslog Server
- Communicating with TCP
- Handling Multiple TCP Streams
- TCP Syslog Server
- TCP Syslog Client
- 28. Software Transactional Memory
- The Basics
- Some Simple Examples
- STM and Safety
- Retrying a Transaction
- What Happens When We Retry?
- Choosing Between Alternatives
- Using Higher Order Code with Transactions
- I/O and STM
- Communication Between Threads
- A Concurrent Web Link Checker
- Checking a Link
- Worker Threads
- Finding Links
- Command-Line Parsing
- Pattern Guards
- Practical Aspects of STM
- Getting Comfortable with Giving Up Control
- Using Invariants
- A. Installing GHC and Haskell Libraries
- Installing GHC
- Windows
- Mac OS X
- Alternatives
- Ubuntu and Debian Linux
- Fedora Linux
- FreeBSD
- Installing Haskell Software
- Automated Download and Installation with cabal
- Installing cabal
- Updating cabals package list
- Installing a library or program
- Building Packages by Hand
- Automated Download and Installation with cabal
- Installing GHC
- B. Characters, Strings, and Escaping Rules
- Writing Character and String Literals
- International Language Support
- Escaping Text
- Single-Character Escape Codes
- Multiline String Literals
- ASCII Control Codes
- Control-with-Character Escapes
- Numeric Escapes
- The Zero-Width Escape Sequence
- Index
- About the Authors
- Colophon
- Copyright