Transcript Haskell 4

More Haskell Functions
Maybe, Either, List, Set, Map
26-Jul-16
Maybe

find (imported from Data.List) takes a predicate and a list, and returns
the first element that satisfies the predicate


But what if there is no such element?



Any Java method that supposed to return an object might instead return null
Thus, it is common to get NullPointerException
In Haskell, find returns a Maybe


find (> 40) [1..10]
In such a case, Java would return null


Example: find (> 4) [1..10]
find :: (a -> Bool) -> [a] -> Maybe a
A Maybe can have the value Nothing or Just something



find (>4) [1..10]
Just 5
find (> 40) [1..10]
Nothing
This works well when combined with pattern matching
Using Maybe

Maybe is a monad


For now, you can just think of it as a “wrapper”
The usual way to deal with monads like this is with a case expression

tell :: Maybe String -> String
tell arg = case arg of Just s -> "Yes, we have " ++ s
Nothing -> "No, sorry!"

GHCi> tell (Just "bananas")
"Yes, we have bananas"

GHCi> tell Nothing
"No, sorry!"
Either

Either takes two types: Either a b

buy :: String -> Int -> Either String Int
buy item cost =
if cost < 20 then Left ("Purchased " ++ item)
else Right cost

*Main> buy "lamp" 15
Left "Purchased lamp"

*Main> buy "sofa" 300
Right 300
Using Either


buy item cost =
if cost < 20 then Left("Purchased " ++ item)
else Right cost
tell_if_bought :: String -> Int -> String
tell_if_bought item price =
case buy item price of
Left s -> "Yes, " ++ s
Right i -> "$" ++ (show price) ++ " was too expensive."

GHCi> tell_if_bought "Sofa" 300
"$300 was too expensive."

GHCi> tell_if_bought "lamp" 16
"Yes, Purchased lamp"
Modules

A Haskell module is like a Java package




A module contains functions, types, and typeclasses
Unlike Java, there are a lot of name collisions, so modules often have to be
imported in a qualified way
To import into GHCi, use :m + module ... module
To import into a program, use import module




import module (f1,..., fn) will import only the named functions
import module hiding (f1,..., fn) will import all but the named
functions
import qualified module imports the module; we call an imported
function fn with module.fn
import qualified module as M imports the module; we call an
imported function fn with M.fn
Typeclasses


A Haskell typeclass is like a Java interface--it tells what
functions an object can support
Some typeclasses and what they support:






Eq -- == and /=
Ord -- < <= >= >
Num -- + - * / and others
Show -- show (enables printing as a string)
Read -- read (conversion from a string to something else)
Functor -- fmap (enables mapping over things)


Lists belong to the Functor typeclass
Monad -- >>=
>>
return
fail
Data.List I


The standard Prelude imports many Data.List functions for
us: map, filter, foldl, etc.
intersperse :: a -> [a] -> [a]


intercalate :: [a] -> [[a]] -> [a]






intercalate " and " ["one", "two", "three"] 
"one and two and three"
transpose :: [[a]] -> [[a]]


intersperse ' ' "hello"  "h e l l o”
transpose [[1,2,3],[4,5,6]]  [[1,4],[2,5],[3,6]]
take 5 (iterate (* 2) 1)  [1,2,4,8,16]
take 5 (drop 5 (iterate (* 2) 1))  [32,64,128,256,512]
take 5 $ drop 5 $ iterate (* 2) 1  [32,64,128,256,512]
takeWhile (/= ' ') "Hello there"  "Hello"
dropWhile (/= ' ') "Hello there"  " there"
Data.List II







The following are especially helpful when dealing with text:
span isLetter "one two three"  ("one"," two three")
break isSpace "one two three"  ("one"," two three")
words "Here are some words." 
["Here","are","some","words."]
unwords $ words "Here are some words." 
"Here are some words."
lines "Roses are red\nViolets are blue" 
["Roses are red","Violets are blue"]
unlines $ lines "Roses are red\nViolets are blue" 
"Roses are red\nViolets are blue\n"
Data.Char

Predicates:







isControl
isSpace (any whitespace)
isLower, isUpper
isAlpha, isAlphaNum, isDigit
isPunctuation
and others
Conversions:



toUpper, toLower, toTitle
digitToInt, intToDigit
ord, chr
Data.Map


Maps are constructed from lists of 2-tuples
Not using a Map:



*Main> let nums = [(1, "one"), (2, "two"), (3, "three"),
(4, "four"), (5, "five")]
*Main> lookup 3 nums
Just "three"
Using a Map:





*Main> let dict = Map.fromList nums
*Main> dict
fromList
[(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")]
*Main> :t Map.fromList
Map.fromList :: (Ord k) => [(k, a)] -> Map.Map k a
*Main> Map.lookup 3 dict
Just "three"
*Main> Map.lookup 7 dict
Nothing
Map operations I

Maps in Haskell are implemented with binary trees, not with
hash tables





Map.empty -- returns an empty map
Map.null map -- tests if a map is empty
Map.singleton key value -- returns a map with one key/value
pair
Map.fromList list -- given a list of 2-tuples, returns a map





Hence, keys must belong to the Ord typeclass
Note: Only the last value is kept if a key is repeated
Map.insert key value map -- inserts a key/value pair
Map.size map -- returns the number of key/value pairs
Map.member key -- tests if the key is in the map
Map.lookup key -- returns Just value or Nothing
Map operations II







Map.map f map -- returns a map in which f has been applied to
each value
Map.filter f map -- returns a map containing only those
key/value pairs for which f value is True
Map.keys map -- returns a list of keys
Map.elems map -- returns a list of values
Map.toList map -- returns a list of (key, value) 2-tuples
Map.fromListWith f list -- given a list of 2-tuples, returns a
map; f is applied to combine duplicate values for the same key
Map.insertWith f key value -- inserts the key/value pair into
the map, using the function f to combine duplicate values for the
same key
Sets in Haskell

Sets, like Maps, are constructed from lists




The import should be qualified to avoid name collisions:
import qualified Data.Set as Set
This is also true for Maps:
import qualified Data.Map as Map
Set.fromList list -- returns a set created from a list
(duplicates are removed)
Set.toList set -- returns an ordered list from a set
Set operations












Set.empty
Set.null set
Set.member value set
Set.union set1 set2
Set.intersection set1 set2
Set.difference set1 set2
Set.size set
Set.singleton value
Set.insert value set
Set.delete value set
Set.map f set
Set.filter f set
Compiling a Haskell program

On UNIX (including Linux and Mac OS):



Compile with ghc --make filename (omit the .hs)
Run with ./filename
On Windows:


Set the PATH environment variable to something like C:\ghc\ghc6.6\bin
Compile with ghc inputfile -o outputfile




Also works on a Mac
compiling hello.hs results in hello.hi, hello.o, and main.exe
Run with outputfile.exe
Running as an interpreted program, without compiling:

runhaskell filename.hs
The End