SlideShare a Scribd company logo
ThoughtWorks




               Haskell Jumpstart
                    David Vollbracht
For this special net presentation the
 part of David Vollbracht will be played
by OS X’s “Kathy” text to speech voice
Agenda
Basic Syntax
Tools to Write This Program
(Almost) Nothing Else
in g
     r n
Wa
     This Intro is Deliberately
            Incomplete
For More Info:
learnyouahaskell.com
Compiler & REPL
GHC
The Glasgow Haskell Compiler
GHCi
Interactive Prompt to Evaluate Expressions
port install ghc
apt-get update && apt-get install ghc6 ghc6-prof ghc6-doc
                    yum install ghc
                    pkg_add -r ghc
                  emerge dev-lang/ghc
         cd /usr/ports/lang/ghc && make install
Basic Syntax
Whitespace Denotes
Function Application
f a b
Function f




             f a b
f a b
Parameter 1
f a b
    Parameter 2
Group Expressions with
       Parens
f (a b)
Function f




      f (a b)
Parameter to f




f (a b)
f (a b)
 Function a
f (a b)
    Parameter to a
g e t
         F o r
 o n’t
D
     Parens change precedence.
      They don’t call functions.
Conditionals:
 If and Case
if a then b else c
Boolean Expression




  if a then b else c
if a then b else c

Expression when a is true
if a then b else c


       Expression when a is false
g e t
         F o r
 o n’t
D
          If ALWAYS has an else.
case a of
b -> x
c -> y
otherwise -> z
Branch expression


case a of
b -> x
c -> y
otherwise -> z
Cases
        case a of
        b -> x
        c -> y
        otherwise -> z
case a of
          Result expressions
b -> x
c -> y
otherwise -> z
case a of
b -> x
c -> y
otherwise -> z
case a of
      b -> x
      c -> y
      otherwise -> z
Default Case
Let Binding
let a = f b
in g a
Binding




let a = f b
in g a
Expression




let a = f b
in g a
let a = f b
   in g a

Expression involving binding
g e t
         F o r
 o n’t
D
                  Bindings are NOT
                      variables.
Multiline Expressions
let a = f b
     c
    d = g e
in g a
let a = f b
     c   Indent after let or of
    d = g e
in g a
let a = f b c

    d = g e
in g a
No indentation needed
when not using ‘let’ or
      ‘case x of’
      (or ‘do’ or ‘where’)
Please indent responsibly
let k = f b
          c
    j = k d
          e
              case a of
in h k j
              b -> f a
                     b
              c -> g a
                     c
Functions
In GHCI, use let
let f a b = <expr>
Function f




let f a b = <expr>
let f a b = <expr>

 Parameter 1
let f a b = <expr>

         Parameter 2
In source file, just define
       at top level
f a b = <expr>
Lists
Ordered Collection
Only One Type of Element
     Variable Length
[a, b, c]
List Constructor




[a, b, c]
[a, b, c]
Element 0   Element 1   Element 2
Type Signatures
"Hello"   :: [Char]
Separates expression from type




"Hello"        :: [Char]
f :: Char -> [Char]
f x = [x, x]
f :: Char -> [Char]
f x = [x, x]


  Function Definition
Type Signature




f :: Char -> [Char]
f x = [x, x]
Polymorphic Functions
         &
 Parameterized Types
head “abc” :: ?
head “abc” :: Char
head :: ?
head :: [a] -> a
head :: [a] -> a
           Type Variable
head :: [a] -> a


      Parameterized Type
head :: [a] -> a
       Polymorphic Function
(Operates on many different types)
head takes a list of some type ‘a’ and
  gives you back one item of type ‘a’



head :: [a] -> a
Pattern Matching
let (x:xs) = [1, 2 ,3]
Pattern Match




let (x:xs) = [1, 2 ,3]
let (x:xs) = [1, 2 ,3]

     1
let (x:xs) = [1, 2 ,3]

       [2, 3]
let (x:xs) = [1, 2 ,3]
f (x:xs) = x * 2 : f xs
Pattern Match




f (x:xs) = x * 2 : f xs
f [] = []
Pattern Match




f [] = []
f [] = []
f (x:xs) = x * 2 : f xs
Matches happen in order of definition


 f [] = []
 f (x:xs) = x * 2 : f xs
Purity & Laziness
Functions Are “Pure”
They Always Produce the Same Result for the Same Value
Good For Reasoning
Good For Compiler Optimizations
Good For Parallel / Concurrent
       Programming
Haskell is Lazy
Because Functions Are Pure,
 Their Evaluation Can Wait
Impure Operations
getLine :: ?
Returns a single line from stdin




   getLine :: ?
getLine ::   String
getLine :: IO String
Means “I’m hiding a side effect”




getLine :: IO String
What can we do with an ‘IO String’?
Get at the String with do notation
main :: do
 s <- getLine
 putStrLn s
Ties together multiple functions that return IO a




main :: do
 s <- getLine
 putStrLn s
main :: do
              s <- getLine
 Unpacks IO putStrLn s
to get at the
underlying
  value
putStrLn :: ?
putStrLn :: String -> IO ()
Void Type



putStrLn :: String -> IO ()
Special Syntax Considerations
g e t
            F o r
    o n’t
D
            When Using do Notation
              let doesn’t use in
main :: do
 let s = "Hello"
 putStrLn s
g e t
       F o r
    o n’t Newline implies a new
D      statement in do notation.

        You must indent if more
             than usual
main = do
 s <- getLine
 if s == "Hello"
  then return "Hi"
  else return "Bye"
Putting it All Together
Some Utility Functions
words ::    String ->
           [String]
Split on whitespace



 words ::              String ->
                      [String]
unwords :: [String] ->
            String
Joins with spaces



unwords :: [String] ->
            String
lines ::    String ->
            [String]

unlines :: [String] ->
            String
getContents :: IO String
Lazily reads all of stdin as a single string



getContents :: IO String
More haskell at
learnyouahaskell.com

More Related Content

What's hot

Functional programming in Python
Functional programming in PythonFunctional programming in Python
Functional programming in Python
Colin Su
 
F# Presentation
F# PresentationF# Presentation
F# Presentation
mrkurt
 
Advanced perl finer points ,pack&amp;unpack,eval,files
Advanced perl   finer points ,pack&amp;unpack,eval,filesAdvanced perl   finer points ,pack&amp;unpack,eval,files
Advanced perl finer points ,pack&amp;unpack,eval,files
Shankar D
 

What's hot (20)

Computer Network Assignment Help
Computer Network Assignment HelpComputer Network Assignment Help
Computer Network Assignment Help
 
Ad hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and CatsAd hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and Cats
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
 
Understanding the REST API of SharePoint 2013
Understanding the REST API of SharePoint 2013Understanding the REST API of SharePoint 2013
Understanding the REST API of SharePoint 2013
 
Functional programming in Python
Functional programming in PythonFunctional programming in Python
Functional programming in Python
 
F# Presentation
F# PresentationF# Presentation
F# Presentation
 
Practical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan HodorogPractical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan Hodorog
 
Intro to Functional Programming
Intro to Functional ProgrammingIntro to Functional Programming
Intro to Functional Programming
 
Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011
 
CBSE Class XI Programming in C++
CBSE Class XI Programming in C++CBSE Class XI Programming in C++
CBSE Class XI Programming in C++
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 4
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 4Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 4
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 4
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming Language
 
Let's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APILet's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java API
 
Advanced perl finer points ,pack&amp;unpack,eval,files
Advanced perl   finer points ,pack&amp;unpack,eval,filesAdvanced perl   finer points ,pack&amp;unpack,eval,files
Advanced perl finer points ,pack&amp;unpack,eval,files
 
Mastering Grammars with PetitParser
Mastering Grammars with PetitParserMastering Grammars with PetitParser
Mastering Grammars with PetitParser
 
Perl6 signatures, types and multicall
Perl6 signatures, types and multicallPerl6 signatures, types and multicall
Perl6 signatures, types and multicall
 
Lecture2 B
Lecture2 BLecture2 B
Lecture2 B
 
Introduction to Swift programming language.
Introduction to Swift programming language.Introduction to Swift programming language.
Introduction to Swift programming language.
 
Swift 2
Swift 2Swift 2
Swift 2
 
7 functions
7  functions7  functions
7 functions
 

Similar to Haskell Jumpstart

Real World Haskell: Lecture 7
Real World Haskell: Lecture 7Real World Haskell: Lecture 7
Real World Haskell: Lecture 7
Bryan O'Sullivan
 
Haskell retrospective
Haskell retrospectiveHaskell retrospective
Haskell retrospective
chenge2k
 
Tech Days Paris Intoduction F# and Collective Intelligence
Tech Days Paris Intoduction F# and Collective IntelligenceTech Days Paris Intoduction F# and Collective Intelligence
Tech Days Paris Intoduction F# and Collective Intelligence
Robert Pickering
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
 
ES6 General Introduction
ES6 General IntroductionES6 General Introduction
ES6 General Introduction
Thomas Johnston
 

Similar to Haskell Jumpstart (20)

Real World Haskell: Lecture 7
Real World Haskell: Lecture 7Real World Haskell: Lecture 7
Real World Haskell: Lecture 7
 
Haskell retrospective
Haskell retrospectiveHaskell retrospective
Haskell retrospective
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Tech Days Paris Intoduction F# and Collective Intelligence
Tech Days Paris Intoduction F# and Collective IntelligenceTech Days Paris Intoduction F# and Collective Intelligence
Tech Days Paris Intoduction F# and Collective Intelligence
 
Cleancode
CleancodeCleancode
Cleancode
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 
Python speleology
Python speleologyPython speleology
Python speleology
 
9 the basic language of functions x
9 the basic language of functions x9 the basic language of functions x
9 the basic language of functions x
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
 
ES6 General Introduction
ES6 General IntroductionES6 General Introduction
ES6 General Introduction
 
Python basic
Python basicPython basic
Python basic
 
Apache pig
Apache pigApache pig
Apache pig
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
Python idiomatico
Python idiomaticoPython idiomatico
Python idiomatico
 

Recently uploaded

Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 

Recently uploaded (20)

The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Ransomware Mallox [EN].pdf
Ransomware         Mallox       [EN].pdfRansomware         Mallox       [EN].pdf
Ransomware Mallox [EN].pdf
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
НАДІЯ ФЕДЮШКО БАЦ «Професійне зростання QA спеціаліста»
НАДІЯ ФЕДЮШКО БАЦ  «Професійне зростання QA спеціаліста»НАДІЯ ФЕДЮШКО БАЦ  «Професійне зростання QA спеціаліста»
НАДІЯ ФЕДЮШКО БАЦ «Професійне зростання QA спеціаліста»
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
КАТЕРИНА АБЗЯТОВА «Ефективне планування тестування ключові аспекти та практ...
КАТЕРИНА АБЗЯТОВА  «Ефективне планування тестування  ключові аспекти та практ...КАТЕРИНА АБЗЯТОВА  «Ефективне планування тестування  ключові аспекти та практ...
КАТЕРИНА АБЗЯТОВА «Ефективне планування тестування ключові аспекти та практ...
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 

Haskell Jumpstart

Editor's Notes

  1. GHCI is the repl that comes with GHC. Once GHC is installed, invoke it with by typing GHCI at the command line. You should set a prompt denoted by Prelude At the prompt we can evaluate any Haskell expression For instance, we can do simple mathematical operations We can also demonstrate Haskell&apos;s string syntax Or actually print a string to standardout To see the myriad of commands available in GHCI, type colon h To quit GHCI, type colon q at the prompt To compile a haskell program from a file, create a dot hs file with the program name you want. Declare a haskell module of the name Main and define the main function with in. When you compile your program, GHC will look in the Main module for the main function. When it is run, your program will start in the main function. Use the --make option to GHC to compile your program into an executable. GHC will create an executable file with the same name as the source file, but with no extension. Execute this file to see your program simply execute it
  2. It should not be surprising that functions play a central role in functional programming. Let&apos;s define some. In GHCI, we must use the let syntax to define a function Start with the let keyword, followed by the function name next list the parameter names, followed by spaces then an equals sign an another space and on the right side write the expression that defines the value of the function. We can use the function simply by typing it&apos;s name followed by any parameters Inside a haskell source file we can define top level functions simply using the equals syntax. There is no need to scope the definition inside of a let expression. You can try out functions from source file in GHCI using the load command. Type the name of the module you would like to load and GHCI will make its functions available to you
  3. One of the most important data structures in Haskell is the list. Lists are written as comma delimited elements enclosed in square braces. The indexing operator can be used to look up elements in a list The head function accepts a list and returns its first element The tail function accepts a list and returns a new list without the head The length function accepts a list and returns its length The plus plus function concatenates two lists The colon function adds an item to the front of a list Strings are lists too. Lists of characters. So we can use head to get the first character of a string we can use tail to strip off the first character of a string and length to get the length of a string of course, the other list functions work on strings too There are lots and lots of list functions available in GHC. Consult the API docs to find out more about the options available
  4. GHCI can help us investigate the haskell type of an expression Using the T command Followed by a haskell expression will show the type of that expression Functions are expressions too, so we can find out their type the T command followed by the function name will show you its type The arrow separates the types in the function signature. The last type is the return type, the rest are parameter type. This function accepts two Bools and returns a String, AKA list of Char There is a very good reason why the parameter and return types are both separated by arrows, but we won&apos;t go into that now.&quot;
  5. There&apos;s a lot more that you can do with pattern matching other than deal with tuples. You can pattern match lists constructed with collun. Start with the Name to bind the first list element to follow it with the collun list constructer and then the Name to bind the rest of the list to. Now we can put a list value in. and see what values were bound The first value in the list, one, was bound to &apos;x&apos;. The rest of the list was bound to &apos;xs&apos;&quot; This pattern match reverses the operation of the colon function, which we can use to build the list back up You can use pattern matching define multiple branches of a function. Ignore the curly braces and semi-colluns. They&apos;re here to make GHCI happy. First we can define than &apos;f&apos; of the empty list is simply the empty list. This is our termination condition for a recursiv definition. With the empty case taken care of, we can safely pattern match a non-empty list and compute on it. Now we have a fuction that multiplies every item in a list by 2 If we define a function that ends up failing to match a pattern, we will get an error message at runtime.
  6. Because haskell is lazy, we can define an infinitely recursiv function. Let&apos;s define a function that starting at &apos;n&apos; and counts up by step &apos;s&apos;, returning a List. The first element of the list is simply &apos;n&apos; The remainder of the list is defined by recursivly calling &apos;f&apos;, using the next number in the list as the new starting point In a strict language we would recurs infinitely as soon as we used the &apos;f&apos; function. In Haskell, however, as long as we only ask for a finite portion of the list we are ok If we try to print out the entire list, then our program goes into a infinite loop. It will keep printing values forever, until we interrupt it with &apos;control c&apos;.
  7. To make this program work we&apos;ll need four pure functions and a main function Functions: singularize, singularizeWords, singularizeLines, singularizeContent Let&apos;s start with the &apos;singularize&apos; function. It&amp;#x2019;s type is String -&gt; String The singuralization scheme is going to be very naive: it will simply strip of a single trailing &apos;s&apos; character We&apos;ll implement the function with recursion, starting with the base case. **Problem is recursive** Using pattern matching on base case: handle when the recursion has no more characters left In this case, we are done so we will simply return an empty list. Let&apos;s start on the second case for the &apos;singuralize&apos; function. - will remove the &amp;#x2018;s&amp;#x2019; character When we encounter a list which is just an &apos;s&apos;, we want to handle it specially. Pattern = [&amp;#x2018;s&amp;#x2019;]. Return [] The final branch of the function will handle the recursion. We&apos;ll Use pattern matching again to pull off the first character from the list. The pattern match is (x:xs) We&apos;ll also use the colon function to build the result. We&apos;ll simply start with the character matched by &apos;c&apos;, since we don&apos;t need to do any operations on it. Next is the collun function, which will be followed by the rest of the word being singularized. We complete our singuralization by recursing back using the remainder of the word. The &apos;singularizeWords&apos; function will use recursion to singularize each word in a list Again, we have the base case of an empty list, which we implement using pattern matching. And we implement the recursion using pattern matching to extract the first word from the list. We will singuralize a single word at a time and using recursion to singularize the rest of the list. The &apos;singularizeLines&apos; function will break each line in a list into words and singuralize them. Again, we use pattern matching for the base case of the recursion. And to extract the first line from the list from the rest of the list. In this case, we use the &apos;words&apos; function to break the line into words, which we then singularize. Then we join the result back together with &apos;unwords&apos;. The collun function will build a new list start with this line of singuralized words. And the rest of the list is build using recursion again. the &apos;singularizeContent&apos; function will break content into lines to be singuralized in this case we don&apos;t need to do any pattern matching because we don&apos;t need recursion.&quot; We simply use &apos;lines&apos; to break up the content, use the &apos;singuralizeLines&apos; function to process them, and &apos;unlines&apos; to join them back together. Finally we get to the &apos;main&apos; function. Until now every function in our application has been pure. We need a little bit of impurity to link it all together. We need to read the content from standard-in, process it, and print it back out. We&apos;ll use &apos;getContents&apos; to lazily read all the content from standard-in. The contents gets unpacked from the IO type into our binding, &apos;s&apos;, as a String. We&apos;ll use the &apos;singularizeContent&apos; content function to process the contentbeing read from standard-in. And finally we use &apos;print string line&apos; to print it out.