Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Haskell Design Patterns
Haskell Design Patterns

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

eBook
€15.99 €23.99
Paperback
€29.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with a Packt Subscription?

Free for first 7 days. $19.99 p/m after that. Cancel any time!
Product feature icon Unlimited ad-free access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon 50+ new titles added per month, including many first-to-market concepts and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon Thousands of reference materials covering every tech concept you need to stay up to date.
Subscribe now
View plans & pricing
Table of content icon View table of contents Preview book icon Preview Book

Haskell Design Patterns

Chapter 2. Patterns for I/O

 

"I believe that the monadic approach to programming, in which actions are first class values, is itself interesting, beautiful and modular. In short, Haskell is the world's finest imperative programming language"

 
 --Tackling the Awkward Squad, Simon Peyton Jones

It is remarkable that we can do side-effecting I/O in a pure functional language!

We start this chapter by establishing I/O as a first-class citizen of Haskell. A the bulk of this chapter is concerned with exploring three styles of I/O programming in Haskell.

We start with the most naïve style: imperative style. From there, we move on to the elegant and concise "lazy I/O", only to run into its severe limitations. The way out is the third and last style we explore: iteratee I/O.

As a binding thread, we carry a simple I/O example through all three styles. We will cover the following topics:

  • I/O as a first-class citizen
  • Imperative I/O
  • Lazy I/O
  • The problem with...

I/O as a first class citizen

The IO monad provides the context in which the side effects may occur, and it also allows us to decouple pure code from the I/O code. In this way, side effects are isolated and made explicit. Let's explore the ways in which I/O participates as a first-class citizen of the language:

import System.IO
import Control.Monad
import Control.Applicative

main = do
  h <- openFile "jabberwocky.txt" ReadMode
  line  <- hGetLine h
  putStrLn . show . words $ line
  hClose h

This code looks imperative in style: it seems as if we are assigning values to the h and line objects, reading from a file, and then leaving side effects with the putStrLn function.

The openFile and hGetLine functions are I/O actions that return a file handle and string, respectively:

  openFile :: FilePath -> IOMode -> IO Handle
  hGetLine ::             Handle -> IO String

The hClose and putStrLn functions are I/O actions that return nothing in particular:

  putStrLn :: String...

Imperative I/O

Even though the Haskell I/O code is purely functional, this does not prevent us from writing imperative style I/O code. Let's start by printing all the lines of the file:

import System.IO
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import Data.Char (chr)

main = do
  h <- openFile "jabberwocky.txt" ReadMode
  loop h
  hClose h
  where
    loop h' = do   
     isEof <- hIsEOF h'
    if isEof
      then putStrLn "DONE..."
      else do
        line  <- hGetLine h'
        print $ words line
        loop h'

Instead of the hGetLine function, let's use a Data.ByteString.hGet function to read from the file in chunks of 8 bytes:

  chunk  <- B.hGet h' 8
  
  print . words $ show chunk
  –- vs
  –- line  <- hGetLine h'
  –- print $ words line

The splitting of a chunk into words is not meaningful anymore. We need to accumulate the chunks until we reach...

Lazy I/O

Of the three main glues of Haskell (HOFs, the type system, and laziness), laziness is different in that it is not a concrete thing in the language, but is instead related to the way the code will be evaluated in the runtime. Laziness is something that we have to know about rather than something we can always see in the code.

Of course, laziness does show in the language, for example, wherever we want to enforce strict evaluation, as with the sequence function:

main = do
  –- lazy IO stream
  let ios = map putStrLn ["this", "won't", "run"]
  
  putStrLn "until ios is 'sequenced'..."
  sequence_ ios –- perform actions

Where:

  sequence_  :: [IO ()] -> IO ()
  sequence_  =  foldr (>>) (return ())

The sequence_ function discards the action results because the (>>) operator discards the results.

In contrast, the sequence function retains the results:

main = do
  h <- openFile "jabberwocky.txt"...

The problems with lazy I/O

Let's use the hGetLine function alongside the hGetContents function:

main = do
  h <- openFile "jabberwocky.txt" ReadMode
  firstLine <- hGetLine h     -- returns a string
  contents  <- hGetContents h -- returns a "promise"

  hClose h           -– close file
  print $ words firstLine
  print $ words contents

We close the file before consuming the firstLine string and the contents stream:

  print $ words firstLine
    ["'Twas","brillig,","and","the","slithy","toves"]
  print $ words contents
    []

The contents is a live stream that gets turned off when the file is closed. The firstLine is an eager string and survives the closing of the file.

The preceding example points to some serious problems with the lazy I/O:

  • The order of the side effects is tied to the order of the lazy evaluation. Because the order of lazy evaluation is not explicit, the order of effects...

Resource management with bracket

So far, we have been explicitly opening and closing files. This is what we call explicit resource management:

main = do
  h <- (openFile "jabberwocky.txt" ReadMode)
  useResource h
  hClose h
where
    useResource h'
         = (stream h') >>= mapM_ putStrLn
    stream h' 
         = hGetContents h' >>= return . lines

Let's look at some higher level abstractions to capture this pattern: open resource, use it, in some way clean up resource. The crudest solution is to just ignore the problem and rely on the garbage collector for the cleanup:

main = do
  contents <- readFile "jabberwocky.txt"
  mapM_ putStrLn (lines contents)

The readFile function encapsulates the file handle, which is then garbage collected when the contents function is garbage collected or when it has been entirely consumed. This is very poor resource management!

It would be more idiomatic to use the wrapper function withFile:

main...

I/O as a first class citizen


The IO Monad provides the context in which side effects may occur, and it also allows us to decouple pure code from I/O code. In this way, side effects are isolated and made explicit. Let's explore the ways in which I/O participates as a first-class citizen of the language:

import System.IO
import Control.Monad
import Control.Applicative

main = do
  h <- openFile "jabberwocky.txt" ReadMode
  line  <- hGetLine h
  putStrLn . show . words $ line
  hClose h

This code looks imperative in style: it seems as if we are assigning values to h and line, reading from a file, and then leaving side effects with the putStrLn function.

The openFile and hGetLine functions are I/O actions that return a file handle and string, respectively:

  openFile :: FilePath -> IOMode -> IO Handle
  hGetLine ::             Handle -> IO String

The hClose and putStrLn functions are I/O actions that return nothing in particular:

  putStrLn :: String -> IO ()
  hClose   :: Handle...

Imperative I/O


Even though Haskell I/O code is purely functional, this does not prevent us from writing imperative style I/O code. Let's start by printing all the lines of the file:

import System.IO
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import Data.Char (chr)

main = do
  h <- openFile "jabberwocky.txt" ReadMode
  loop h
  hClose h
  where
    loop h' = do   
     isEof <- hIsEOF h'
     if isEof
      then putStrLn "DONE..."
      else do
        line  <- hGetLine h'
        print $ words line
        loop h'

Instead of the hGetLine function, let's use a Data.ByteString.hGet function to read from the file in chunks of 8 bytes:

  chunk  <- B.hGet h' 8
  
  print . words $ show chunk
  –- vs
  –- line  <- hGetLine h'
  –- print $ words line

The splitting of a chunk into words is not meaningful anymore. We need to accumulate the chunks until we reach the end of a line and then capture the accumulated line and possible remainder:

data...
Left arrow icon Right arrow icon

Key benefits

  • • 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

Description

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

Who is this book 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.

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Nov 06, 2015
Length: 166 pages
Edition : 1st
Language : English
ISBN-13 : 9781783988723
Category :
Languages :

What do you get with a Packt Subscription?

Free for first 7 days. $19.99 p/m after that. Cancel any time!
Product feature icon Unlimited ad-free access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon 50+ new titles added per month, including many first-to-market concepts and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon Thousands of reference materials covering every tech concept you need to stay up to date.
Subscribe now
View plans & pricing

Product Details

Publication date : Nov 06, 2015
Length: 166 pages
Edition : 1st
Language : English
ISBN-13 : 9781783988723
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 113.97
Haskell High Performance Programming
€41.99
Haskell Design Patterns
€29.99
Haskell Cookbook
€41.99
Total 113.97 Stars icon

Table of Contents

8 Chapters
1. Functional Patterns – the Building Blocks Chevron down icon Chevron up icon
2. Patterns for I/O Chevron down icon Chevron up icon
3. Patterns of Composition Chevron down icon Chevron up icon
4. Patterns of Folding and Traversing Chevron down icon Chevron up icon
5. Patterns of Type Abstraction Chevron down icon Chevron up icon
6. Patterns of Generic Programming Chevron down icon Chevron up icon
7. Patterns of Kind Abstraction Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.1
(9 Ratings)
5 star 55.6%
4 star 22.2%
3 star 11.1%
2 star 0%
1 star 11.1%
Filter icon Filter
Top Reviews

Filter reviews by




ruben Jan 16, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
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.
Amazon Verified review Amazon
Andre M. Van Meulebrouck Sep 15, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I love this book; it is concise, interesting, insightful, and well written. Lots of food for thought in this book, regardless whether you use Haskell or not.It also provides a behind-the-scenes look at the evolution of Haskell as a language that is very worthwhile, fair, balanced, and objective.Judicious use of quotes is tastefully interjected, which helps to frame the discussion.The book eloquently ends with a quote (from "History of Haskell") which I will summarize in my own words as a conjecture about a day when Haskell will become a distant memory, but when that day comes it will live on in the genes of other technologies which it influenced.Well said!What a gem of a book. I'm glad I didn't miss it.
Amazon Verified review Amazon
SuJo Jan 30, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I enjoyed reading over this book, Haskell Design Patterns helps approach real world situations that you will experience at one time or another as a programmer. Recursion was covered nicely, my favorite functions are the I/O functions which are covered in Chapter 2.
Amazon Verified review Amazon
Johnny Dec 27, 2018
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I'm blown away by the things I'm learning, and the great way that concepts are explained. Examples: Currying and Tail Recursion. I thought I knew all there was to about currying - I learned it in my CS undergrad after all. But oh, it's totally possible to write functions in an uncurried style by wrapping the parameters in a tuple. That never occurred to me. And then the follow-up with advantages and disadvantages of that with a note about what's idiomatic. Perfect. The book doesn't insult the intelligence of the reader, who's most likely been doing development in other languages.And Tail Recursion --- I didn't quite remember how it works, and sort of had been ignoring this as an 'implementation detail' of programming libraries. But here the explanation and unrolled call stack make it plain of day what's happening, and what the difference is.Lol, two years in to Haskell development, I consider myself to be just an "advanced beginner".
Amazon Verified review Amazon
Perry Nally Jan 31, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Was helpful learning the design patterns, which is what it's title says it covers. The examples are clear enough to grasp the pattern. If you're new to Haskell, you may want to take it slowly to verify the programs. Functional programming requires a different approach, and this book helped enlighten me.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is included in a Packt subscription? Chevron down icon Chevron up icon

A subscription provides you with full access to view all Packt and licnesed content online, this includes exclusive access to Early Access titles. Depending on the tier chosen you can also earn credits and discounts to use for owning content

How can I cancel my subscription? Chevron down icon Chevron up icon

To cancel your subscription with us simply go to the account page - found in the top right of the page or at https://subscription.packtpub.com/my-account/subscription - From here you will see the ‘cancel subscription’ button in the grey box with your subscription information in.

What are credits? Chevron down icon Chevron up icon

Credits can be earned from reading 40 section of any title within the payment cycle - a month starting from the day of subscription payment. You also earn a Credit every month if you subscribe to our annual or 18 month plans. Credits can be used to buy books DRM free, the same way that you would pay for a book. Your credits can be found in the subscription homepage - subscription.packtpub.com - clicking on ‘the my’ library dropdown and selecting ‘credits’.

What happens if an Early Access Course is cancelled? Chevron down icon Chevron up icon

Projects are rarely cancelled, but sometimes it's unavoidable. If an Early Access course is cancelled or excessively delayed, you can exchange your purchase for another course. For further details, please contact us here.

Where can I send feedback about an Early Access title? Chevron down icon Chevron up icon

If you have any feedback about the product you're reading, or Early Access in general, then please fill out a contact form here and we'll make sure the feedback gets to the right team. 

Can I download the code files for Early Access titles? Chevron down icon Chevron up icon

We try to ensure that all books in Early Access have code available to use, download, and fork on GitHub. This helps us be more agile in the development of the book, and helps keep the often changing code base of new versions and new technologies as up to date as possible. Unfortunately, however, there will be rare cases when it is not possible for us to have downloadable code samples available until publication.

When we publish the book, the code files will also be available to download from the Packt website.

How accurate is the publication date? Chevron down icon Chevron up icon

The publication date is as accurate as we can be at any point in the project. Unfortunately, delays can happen. Often those delays are out of our control, such as changes to the technology code base or delays in the tech release. We do our best to give you an accurate estimate of the publication date at any given time, and as more chapters are delivered, the more accurate the delivery date will become.

How will I know when new chapters are ready? Chevron down icon Chevron up icon

We'll let you know every time there has been an update to a course that you've bought in Early Access. You'll get an email to let you know there has been a new chapter, or a change to a previous chapter. The new chapters are automatically added to your account, so you can also check back there any time you're ready and download or read them online.

I am a Packt subscriber, do I get Early Access? Chevron down icon Chevron up icon

Yes, all Early Access content is fully available through your subscription. You will need to have a paid for or active trial subscription in order to access all titles.

How is Early Access delivered? Chevron down icon Chevron up icon

Early Access is currently only available as a PDF or through our online reader. As we make changes or add new chapters, the files in your Packt account will be updated so you can download them again or view them online immediately.

How do I buy Early Access content? Chevron down icon Chevron up icon

Early Access is a way of us getting our content to you quicker, but the method of buying the Early Access course is still the same. Just find the course you want to buy, go through the check-out steps, and you’ll get a confirmation email from us with information and a link to the relevant Early Access courses.

What is Early Access? Chevron down icon Chevron up icon

Keeping up to date with the latest technology is difficult; new versions, new frameworks, new techniques. This feature gives you a head-start to our content, as it's being created. With Early Access you'll receive each chapter as it's written, and get regular updates throughout the product's development, as well as the final course as soon as it's ready.We created Early Access as a means of giving you the information you need, as soon as it's available. As we go through the process of developing a course, 99% of it can be ready but we can't publish until that last 1% falls in to place. Early Access helps to unlock the potential of our content early, to help you start your learning when you need it most. You not only get access to every chapter as it's delivered, edited, and updated, but you'll also get the finalized, DRM-free product to download in any format you want when it's published. As a member of Packt, you'll also be eligible for our exclusive offers, including a free course every day, and discounts on new and popular titles.