Understanding Haskell Functions: Maybe, Either, List, Set, and Map
This text explores fundamental Haskell concepts including the functions Maybe, Either, List, Set, and Map. It demonstrates how the `Maybe.find` function safely returns a value or `Nothing`, avoiding null pointer exceptions common in languages like Java. Additionally, the `Either` type supports error handling with two distinct value types. The description also covers the structure of Haskell modules and the syntax for typeclasses, including commonly used functions. The text offers examples from the Data.List and Data.Map libraries to illustrate practical applications and operations.
Understanding Haskell Functions: Maybe, Either, List, Set, and Map
E N D
Presentation Transcript
1. 16-Sep-12 More Haskell Functions Maybe, Either, List, Set, Map
2. Maybe find takes a predicate and a list, and returns the first element that satisfies the predicate
Example: find (> 4) [1..10]
But what if there is no such element?
find (> 40) [1..10]
In such a case, Java would return null
Theres nothing in the syntax that warns you this might happen
Thus, you can get a NullPointerException
In Haskell, find returns a Maybe
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
3. Either Either takes two types: Either a b
buy :: String -> Int -> Either String Intbuy item cost = if cost < 20 then Left ("Purchased " ++ item) else Right cost
*Main> buy "lamp" 15Left "Purchased lamp"
*Main> buy "sofa" 300Right 300
4. 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
5. 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
6. Data.List I The standard Prelude imports many Data.List functions for us: map, filter, foldl, etc.
intersperse :: a -> [a] -> [a]
intersperse ' ' "hello" ? "h e l l o
intercalate :: [a] -> [[a]] -> [a]
intercalate " and " ["one", "two", "three"] ? "one and two and three"
transpose :: [[a]] -> [[a]]
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"
7. 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"
8. Data.Char Predicates:
isControl
isSpace (any whitespace)
isLower, isUpper
isAlpha, isAlphaNum, isDigit
isPunctuation
and others
Conversions:
toUpper, toLower, toTitle
digitToInt, intToDigit
ord, chr
9. 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 numsJust "three"
Using a Map:
*Main> let dict = Map.fromList nums
*Main> dictfromList [(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")]
*Main> :t Map.fromListMap.fromList :: (Ord k) => [(k, a)] -> Map.Map k a
*Main> Map.lookup 3 dictJust "three"
*Main> Map.lookup 7 dictNothing
10. Map operations I Maps in Haskell are implemented with binary trees, not with hash tables
Hence, keys must belong to the Ord typeclass
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
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
11. 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
12. Sets in Haskell Sets, like Maps, are constructed from lists
Like Maps, the import should be qualified to avoid name collisions:import qualified Data.Set as Set
Set.fromList list -- returns a set created from a list (duplicates are removed)
Set.toList set -- returns an ordered list from a set
13. 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
14. 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\ghc-6.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
15. The End