Transcript
Page 1: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

Apr 11, 2023

More Haskell Functions

Maybe, Either, List, Set, Map

Page 2: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

Maybe find (imported from Data.List) 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 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 :: (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

Page 3: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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 -> Stringtell 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!"

Page 4: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

Page 5: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

Using Either buy item cost =

if cost < 20 then Left("Purchased " ++ item)else Right cost

tell_if_bought :: String -> Int -> Stringtell_if_bought item price = case buy item price of

Left s -> "Yes, " ++ sRight 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"

Page 6: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

Page 7: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

Page 8: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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"

Page 9: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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"

Page 10: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

Data.Char

Predicates: isControl isSpace (any whitespace) isLower, isUpper isAlpha, isAlphaNum, isDigit isPunctuation and others

Conversions: toUpper, toLower, toTitle digitToInt, intToDigit ord, chr

Page 11: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

fromList [(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

Page 12: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

Page 13: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

Page 14: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

Page 15: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

Page 16: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

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

Page 17: 15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map

The End


Top Related