Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh...

74
Programming in Haskell: Lecture 8 S P Suresh September 4, 2019 Suresh PRGH 2019: Lecture 8 September 4, 2019 1 / 19

Transcript of Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh...

Page 1: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Programming in Haskell: Lecture 8

S P Suresh

September 4, 2019

Suresh PRGH 2019: Lecture 8 September 4, 2019 1 / 19

Page 2: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: reverse

• The built-in reverse takes time proportional to n, the length of the list

• Strategy: Repeatedly extract head and place it in front of anaccumulator list• The list is automatically reversed

reverse l = revInto [] lwhere

revInto a [] = arevInto a (x:xs) = revInto (x:a) xs

Suresh PRGH 2019: Lecture 8 September 4, 2019 2 / 19

Page 3: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: reverse

• The built-in reverse takes time proportional to n, the length of the list• Strategy: Repeatedly extract head and place it in front of anaccumulator list

• The list is automatically reversedreverse l = revInto [] l

whererevInto a [] = arevInto a (x:xs) = revInto (x:a) xs

Suresh PRGH 2019: Lecture 8 September 4, 2019 2 / 19

Page 4: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: reverse

• The built-in reverse takes time proportional to n, the length of the list• Strategy: Repeatedly extract head and place it in front of anaccumulator list• The list is automatically reversed

reverse l = revInto [] lwhere

revInto a [] = arevInto a (x:xs) = revInto (x:a) xs

Suresh PRGH 2019: Lecture 8 September 4, 2019 2 / 19

Page 5: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in functions: take and drop

• take n l returns the first n elements of l

• drop n l returns all but the first n elements of l• take n l ++ drop n l == l

take _ [] = []take n (x:xs) | n <= 0 = []

| otherwise = x:take (n-1) xs

drop _ [] = []drop n (x:xs) | n <= 0 = x:xs

| otherwise = drop (n-1) xs

Suresh PRGH 2019: Lecture 8 September 4, 2019 3 / 19

Page 6: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in functions: take and drop

• take n l returns the first n elements of l• drop n l returns all but the first n elements of l

• take n l ++ drop n l == l

take _ [] = []take n (x:xs) | n <= 0 = []

| otherwise = x:take (n-1) xs

drop _ [] = []drop n (x:xs) | n <= 0 = x:xs

| otherwise = drop (n-1) xs

Suresh PRGH 2019: Lecture 8 September 4, 2019 3 / 19

Page 7: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in functions: take and drop

• take n l returns the first n elements of l• drop n l returns all but the first n elements of l• take n l ++ drop n l == l

take _ [] = []take n (x:xs) | n <= 0 = []

| otherwise = x:take (n-1) xs

drop _ [] = []drop n (x:xs) | n <= 0 = x:xs

| otherwise = drop (n-1) xs

Suresh PRGH 2019: Lecture 8 September 4, 2019 3 / 19

Page 8: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: splitAt

• splitAt n l = (take n l, drop n l)

• Can be defined directly:splitAt _ [] = ([], [])splitAt n (x:xs)

| n < = 0 = ([], x:xs)| otherwise = (x:fst (splitAt (n-1) xs),

snd (splitAt (n-1) xs))

• Two recursive calls to splitAt (n-1)

• Very inefficient – time proportional to 2n

Suresh PRGH 2019: Lecture 8 September 4, 2019 4 / 19

Page 9: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: splitAt

• splitAt n l = (take n l, drop n l)

• Can be defined directly:splitAt _ [] = ([], [])splitAt n (x:xs)

| n < = 0 = ([], x:xs)| otherwise = (x:fst (splitAt (n-1) xs),

snd (splitAt (n-1) xs))

• Two recursive calls to splitAt (n-1)

• Very inefficient – time proportional to 2n

Suresh PRGH 2019: Lecture 8 September 4, 2019 4 / 19

Page 10: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: splitAt

• splitAt n l = (take n l, drop n l)

• Can be defined directly:splitAt _ [] = ([], [])splitAt n (x:xs)

| n < = 0 = ([], x:xs)| otherwise = (x:fst (splitAt (n-1) xs),

snd (splitAt (n-1) xs))

• Two recursive calls to splitAt (n-1)

• Very inefficient – time proportional to 2n

Suresh PRGH 2019: Lecture 8 September 4, 2019 4 / 19

Page 11: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: splitAt

• splitAt n l = (take n l, drop n l)

• Can be defined directly:splitAt _ [] = ([], [])splitAt n (x:xs)

| n < = 0 = ([], x:xs)| otherwise = (x:fst (splitAt (n-1) xs),

snd (splitAt (n-1) xs))

• Two recursive calls to splitAt (n-1)

• Very inefficient – time proportional to 2n

Suresh PRGH 2019: Lecture 8 September 4, 2019 4 / 19

Page 12: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: splitAt

• Much better version:splitAt _ [] = ([], [])splitAt n (x:xs)

| n < = 0 = ([], x:xs)| otherwise = (x:ys, zs)

where (ys, zs) = splitAt (n-1) xs

• Only one recursive call to splitAt (n-1)

• Running time is proportional to n

• Local definitions helps avoid repeated computation of same value

Suresh PRGH 2019: Lecture 8 September 4, 2019 5 / 19

Page 13: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: splitAt

• Much better version:splitAt _ [] = ([], [])splitAt n (x:xs)

| n < = 0 = ([], x:xs)| otherwise = (x:ys, zs)

where (ys, zs) = splitAt (n-1) xs

• Only one recursive call to splitAt (n-1)

• Running time is proportional to n

• Local definitions helps avoid repeated computation of same value

Suresh PRGH 2019: Lecture 8 September 4, 2019 5 / 19

Page 14: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: splitAt

• Much better version:splitAt _ [] = ([], [])splitAt n (x:xs)

| n < = 0 = ([], x:xs)| otherwise = (x:ys, zs)

where (ys, zs) = splitAt (n-1) xs

• Only one recursive call to splitAt (n-1)

• Running time is proportional to n

• Local definitions helps avoid repeated computation of same value

Suresh PRGH 2019: Lecture 8 September 4, 2019 5 / 19

Page 15: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in function: splitAt

• Much better version:splitAt _ [] = ([], [])splitAt n (x:xs)

| n < = 0 = ([], x:xs)| otherwise = (x:ys, zs)

where (ys, zs) = splitAt (n-1) xs

• Only one recursive call to splitAt (n-1)

• Running time is proportional to n

• Local definitions helps avoid repeated computation of same value

Suresh PRGH 2019: Lecture 8 September 4, 2019 5 / 19

Page 16: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

The datatype Char

• Values are written with single quotes

• 'a', '3', '%', '#', …• Character symbols stored in a table (e.g. ASCII, Unicode)• Functions ord and chr connect characters and table• Inverses of each other: c == chr (ord c), j == ord (chr j)

• Note: import Data.Char to use ord and chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 6 / 19

Page 17: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

The datatype Char

• Values are written with single quotes• 'a', '3', '%', '#', …

• Character symbols stored in a table (e.g. ASCII, Unicode)• Functions ord and chr connect characters and table• Inverses of each other: c == chr (ord c), j == ord (chr j)

• Note: import Data.Char to use ord and chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 6 / 19

Page 18: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

The datatype Char

• Values are written with single quotes• 'a', '3', '%', '#', …• Character symbols stored in a table (e.g. ASCII, Unicode)

• Functions ord and chr connect characters and table• Inverses of each other: c == chr (ord c), j == ord (chr j)

• Note: import Data.Char to use ord and chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 6 / 19

Page 19: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

The datatype Char

• Values are written with single quotes• 'a', '3', '%', '#', …• Character symbols stored in a table (e.g. ASCII, Unicode)• Functions ord and chr connect characters and table

• Inverses of each other: c == chr (ord c), j == ord (chr j)

• Note: import Data.Char to use ord and chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 6 / 19

Page 20: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

The datatype Char

• Values are written with single quotes• 'a', '3', '%', '#', …• Character symbols stored in a table (e.g. ASCII, Unicode)• Functions ord and chr connect characters and table• Inverses of each other: c == chr (ord c), j == ord (chr j)

• Note: import Data.Char to use ord and chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 6 / 19

Page 21: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

The datatype Char

• Values are written with single quotes• 'a', '3', '%', '#', …• Character symbols stored in a table (e.g. ASCII, Unicode)• Functions ord and chr connect characters and table• Inverses of each other: c == chr (ord c), j == ord (chr j)

• Note: import Data.Char to use ord and chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 6 / 19

Page 22: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: toUpper

• Convert lowercase letters to uppercase

• Brute-force, enumerate all cases:toUpper 'a' = 'A'toUpper 'b' = 'B'toUpper 'c' = 'C'

...

...toUpper 'x' = 'X'toUpper 'y' = 'Y'toUpper 'z' = 'Z'

Suresh PRGH 2019: Lecture 8 September 4, 2019 7 / 19

Page 23: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: toUpper

• Convert lowercase letters to uppercase• Brute-force, enumerate all cases:

toUpper 'a' = 'A'toUpper 'b' = 'B'toUpper 'c' = 'C'

...

...toUpper 'x' = 'X'toUpper 'y' = 'Y'toUpper 'z' = 'Z'

Suresh PRGH 2019: Lecture 8 September 4, 2019 7 / 19

Page 24: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: toUpper

• 'a', …, 'z' have contiguous ord values

• Same with 'A', …, 'Z' and '0', …, '9'• Can compare two characters to see which one appears earlier in thetable• Smarter solution for toUpper:

toUpper :: Char -> ChartoUpper c

| ('a' <= c && c <= 'z')= chr (ord c + (ord 'A' - ord 'a'))

| otherwise = c

Suresh PRGH 2019: Lecture 8 September 4, 2019 8 / 19

Page 25: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: toUpper

• 'a', …, 'z' have contiguous ord values• Same with 'A', …, 'Z' and '0', …, '9'

• Can compare two characters to see which one appears earlier in thetable• Smarter solution for toUpper:

toUpper :: Char -> ChartoUpper c

| ('a' <= c && c <= 'z')= chr (ord c + (ord 'A' - ord 'a'))

| otherwise = c

Suresh PRGH 2019: Lecture 8 September 4, 2019 8 / 19

Page 26: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: toUpper

• 'a', …, 'z' have contiguous ord values• Same with 'A', …, 'Z' and '0', …, '9'• Can compare two characters to see which one appears earlier in thetable

• Smarter solution for toUpper:toUpper :: Char -> ChartoUpper c

| ('a' <= c && c <= 'z')= chr (ord c + (ord 'A' - ord 'a'))

| otherwise = c

Suresh PRGH 2019: Lecture 8 September 4, 2019 8 / 19

Page 27: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: toUpper

• 'a', …, 'z' have contiguous ord values• Same with 'A', …, 'Z' and '0', …, '9'• Can compare two characters to see which one appears earlier in thetable• Smarter solution for toUpper:

toUpper :: Char -> ChartoUpper c

| ('a' <= c && c <= 'z')= chr (ord c + (ord 'A' - ord 'a'))

| otherwise = c

Suresh PRGH 2019: Lecture 8 September 4, 2019 8 / 19

Page 28: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in functions on Char

• Character classification: isSpace, isUpper, isLower, isDigit, isAlpha,isAlphaNum

• Case conversion: toLower, toUpper• Single digit characters: digitToInt, intToDigit• Numeric representation: ord, chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 9 / 19

Page 29: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in functions on Char

• Character classification: isSpace, isUpper, isLower, isDigit, isAlpha,isAlphaNum

• Case conversion: toLower, toUpper

• Single digit characters: digitToInt, intToDigit• Numeric representation: ord, chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 9 / 19

Page 30: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in functions on Char

• Character classification: isSpace, isUpper, isLower, isDigit, isAlpha,isAlphaNum

• Case conversion: toLower, toUpper• Single digit characters: digitToInt, intToDigit

• Numeric representation: ord, chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 9 / 19

Page 31: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Built-in functions on Char

• Character classification: isSpace, isUpper, isLower, isDigit, isAlpha,isAlphaNum

• Case conversion: toLower, toUpper• Single digit characters: digitToInt, intToDigit• Numeric representation: ord, chr

Suresh PRGH 2019: Lecture 8 September 4, 2019 9 / 19

Page 32: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Strings

• A string is a sequence of characters

• In Haskell, String is a synonym for [Char]• Type synonyms are defined using the type keyword

type String = [Char]

• Special syntax for strings

• "hello" is syntactic sugar for ['h','e','l','l','o']• The empty string, denoted, "", is just []• Recall: [] is the empty list of all types

• Usual list functions like length, reverse, …can be used on String

Suresh PRGH 2019: Lecture 8 September 4, 2019 10 / 19

Page 33: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Strings

• A string is a sequence of characters• In Haskell, String is a synonym for [Char]

• Type synonyms are defined using the type keywordtype String = [Char]

• Special syntax for strings

• "hello" is syntactic sugar for ['h','e','l','l','o']• The empty string, denoted, "", is just []• Recall: [] is the empty list of all types

• Usual list functions like length, reverse, …can be used on String

Suresh PRGH 2019: Lecture 8 September 4, 2019 10 / 19

Page 34: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Strings

• A string is a sequence of characters• In Haskell, String is a synonym for [Char]• Type synonyms are defined using the type keyword

type String = [Char]

• Special syntax for strings

• "hello" is syntactic sugar for ['h','e','l','l','o']• The empty string, denoted, "", is just []• Recall: [] is the empty list of all types

• Usual list functions like length, reverse, …can be used on String

Suresh PRGH 2019: Lecture 8 September 4, 2019 10 / 19

Page 35: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Strings

• A string is a sequence of characters• In Haskell, String is a synonym for [Char]• Type synonyms are defined using the type keyword

type String = [Char]

• Special syntax for strings

• "hello" is syntactic sugar for ['h','e','l','l','o']• The empty string, denoted, "", is just []• Recall: [] is the empty list of all types

• Usual list functions like length, reverse, …can be used on String

Suresh PRGH 2019: Lecture 8 September 4, 2019 10 / 19

Page 36: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Strings

• A string is a sequence of characters• In Haskell, String is a synonym for [Char]• Type synonyms are defined using the type keyword

type String = [Char]

• Special syntax for strings• "hello" is syntactic sugar for ['h','e','l','l','o']

• The empty string, denoted, "", is just []• Recall: [] is the empty list of all types

• Usual list functions like length, reverse, …can be used on String

Suresh PRGH 2019: Lecture 8 September 4, 2019 10 / 19

Page 37: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Strings

• A string is a sequence of characters• In Haskell, String is a synonym for [Char]• Type synonyms are defined using the type keyword

type String = [Char]

• Special syntax for strings• "hello" is syntactic sugar for ['h','e','l','l','o']• The empty string, denoted, "", is just []

• Recall: [] is the empty list of all types• Usual list functions like length, reverse, …can be used on String

Suresh PRGH 2019: Lecture 8 September 4, 2019 10 / 19

Page 38: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Strings

• A string is a sequence of characters• In Haskell, String is a synonym for [Char]• Type synonyms are defined using the type keyword

type String = [Char]

• Special syntax for strings• "hello" is syntactic sugar for ['h','e','l','l','o']• The empty string, denoted, "", is just []• Recall: [] is the empty list of all types

• Usual list functions like length, reverse, …can be used on String

Suresh PRGH 2019: Lecture 8 September 4, 2019 10 / 19

Page 39: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Strings

• A string is a sequence of characters• In Haskell, String is a synonym for [Char]• Type synonyms are defined using the type keyword

type String = [Char]

• Special syntax for strings• "hello" is syntactic sugar for ['h','e','l','l','o']• The empty string, denoted, "", is just []• Recall: [] is the empty list of all types

• Usual list functions like length, reverse, …can be used on String

Suresh PRGH 2019: Lecture 8 September 4, 2019 10 / 19

Page 40: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: occurs

• Search for a character in a string

• occurs c s returns True exactly when c occurs in string

occurs :: Char -> String -> Booloccurs _ "" = Falseoccurs c (a:as) = c == a || occurs c as

• Just a version of the general function elem on lists

Suresh PRGH 2019: Lecture 8 September 4, 2019 11 / 19

Page 41: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: occurs

• Search for a character in a string• occurs c s returns True exactly when c occurs in string

occurs :: Char -> String -> Booloccurs _ "" = Falseoccurs c (a:as) = c == a || occurs c as

• Just a version of the general function elem on lists

Suresh PRGH 2019: Lecture 8 September 4, 2019 11 / 19

Page 42: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: occurs

• Search for a character in a string• occurs c s returns True exactly when c occurs in string

occurs :: Char -> String -> Booloccurs _ "" = Falseoccurs c (a:as) = c == a || occurs c as

• Just a version of the general function elem on lists

Suresh PRGH 2019: Lecture 8 September 4, 2019 11 / 19

Page 43: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: capitalize

• Convert all lowercase letters in a string to uppercasecapitalize :: String -> Stringcapitalize "" = ""capitalize (a:as) = toUpper a : capitalize as

• Apply the same function (toUpper) to every element in the list• Wewill revisit this pattern later

Suresh PRGH 2019: Lecture 8 September 4, 2019 12 / 19

Page 44: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: capitalize

• Convert all lowercase letters in a string to uppercasecapitalize :: String -> Stringcapitalize "" = ""capitalize (a:as) = toUpper a : capitalize as

• Apply the same function (toUpper) to every element in the list

• Wewill revisit this pattern later

Suresh PRGH 2019: Lecture 8 September 4, 2019 12 / 19

Page 45: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: capitalize

• Convert all lowercase letters in a string to uppercasecapitalize :: String -> Stringcapitalize "" = ""capitalize (a:as) = toUpper a : capitalize as

• Apply the same function (toUpper) to every element in the list• Wewill revisit this pattern later

Suresh PRGH 2019: Lecture 8 September 4, 2019 12 / 19

Page 46: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: position

• position c s : first position in swhere c occurs

• Return length s if no occurrence of c in s• position 'a' "battle axe" = 1

• position 'd' "battle axe" = 10

• Simple recursive programposition :: Char -> String -> Intposition c "" = 0position c (d:ds)

| c == d = 0| otherwise = 1 + (position c ds)

Suresh PRGH 2019: Lecture 8 September 4, 2019 13 / 19

Page 47: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: position

• position c s : first position in swhere c occurs• Return length s if no occurrence of c in s

• position 'a' "battle axe" = 1

• position 'd' "battle axe" = 10

• Simple recursive programposition :: Char -> String -> Intposition c "" = 0position c (d:ds)

| c == d = 0| otherwise = 1 + (position c ds)

Suresh PRGH 2019: Lecture 8 September 4, 2019 13 / 19

Page 48: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: position

• position c s : first position in swhere c occurs• Return length s if no occurrence of c in s• position 'a' "battle axe" = 1

• position 'd' "battle axe" = 10

• Simple recursive programposition :: Char -> String -> Intposition c "" = 0position c (d:ds)

| c == d = 0| otherwise = 1 + (position c ds)

Suresh PRGH 2019: Lecture 8 September 4, 2019 13 / 19

Page 49: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: position

• position c s : first position in swhere c occurs• Return length s if no occurrence of c in s• position 'a' "battle axe" = 1

• position 'd' "battle axe" = 10

• Simple recursive programposition :: Char -> String -> Intposition c "" = 0position c (d:ds)

| c == d = 0| otherwise = 1 + (position c ds)

Suresh PRGH 2019: Lecture 8 September 4, 2019 13 / 19

Page 50: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: position

• position c s : first position in swhere c occurs• Return length s if no occurrence of c in s• position 'a' "battle axe" = 1

• position 'd' "battle axe" = 10

• Simple recursive programposition :: Char -> String -> Intposition c "" = 0position c (d:ds)

| c == d = 0| otherwise = 1 + (position c ds)

Suresh PRGH 2019: Lecture 8 September 4, 2019 13 / 19

Page 51: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Maybe

• position c s == length s indicates that c does not occur in s

• Need a more direct way to indicate non-occurrence• Use the type Maybe Int

• For any type t, Maybe t is also type• Values of type Maybe t:

• Nothing• Just x for all x of type t

Suresh PRGH 2019: Lecture 8 September 4, 2019 14 / 19

Page 52: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Maybe

• position c s == length s indicates that c does not occur in s• Need a more direct way to indicate non-occurrence

• Use the type Maybe Int

• For any type t, Maybe t is also type• Values of type Maybe t:

• Nothing• Just x for all x of type t

Suresh PRGH 2019: Lecture 8 September 4, 2019 14 / 19

Page 53: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Maybe

• position c s == length s indicates that c does not occur in s• Need a more direct way to indicate non-occurrence• Use the type Maybe Int

• For any type t, Maybe t is also type• Values of type Maybe t:

• Nothing• Just x for all x of type t

Suresh PRGH 2019: Lecture 8 September 4, 2019 14 / 19

Page 54: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Maybe

• position c s == length s indicates that c does not occur in s• Need a more direct way to indicate non-occurrence• Use the type Maybe Int

• For any type t, Maybe t is also type

• Values of type Maybe t:

• Nothing• Just x for all x of type t

Suresh PRGH 2019: Lecture 8 September 4, 2019 14 / 19

Page 55: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Maybe

• position c s == length s indicates that c does not occur in s• Need a more direct way to indicate non-occurrence• Use the type Maybe Int

• For any type t, Maybe t is also type• Values of type Maybe t:

• Nothing• Just x for all x of type t

Suresh PRGH 2019: Lecture 8 September 4, 2019 14 / 19

Page 56: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Maybe

• position c s == length s indicates that c does not occur in s• Need a more direct way to indicate non-occurrence• Use the type Maybe Int

• For any type t, Maybe t is also type• Values of type Maybe t:• Nothing

• Just x for all x of type t

Suresh PRGH 2019: Lecture 8 September 4, 2019 14 / 19

Page 57: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Maybe

• position c s == length s indicates that c does not occur in s• Need a more direct way to indicate non-occurrence• Use the type Maybe Int

• For any type t, Maybe t is also type• Values of type Maybe t:• Nothing• Just x for all x of type t

Suresh PRGH 2019: Lecture 8 September 4, 2019 14 / 19

Page 58: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: a better position

• Return Nothing if c does not occur in sposition :: Char -> String -> Maybe Intposition c "" = Nothingposition c (d:ds)

| c == d = Just 0| otherwise = case position ds of

Nothing -> NothingJust x -> Just (x+1)

Suresh PRGH 2019: Lecture 8 September 4, 2019 15 / 19

Page 59: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Counting words

• wordc : count the number of words in a string

• Words separated by white space: ' ', '\t', '\n'&c.• Maybe we can count the number of white spaces in the string:

wordc :: String -> Intwordc "" = 0wordc (d:ds)

| isSpace d = 1 + wordc ds| otherwise = wordc ds

• Not correct: wordc "abc d"will return 5

Suresh PRGH 2019: Lecture 8 September 4, 2019 16 / 19

Page 60: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Counting words

• wordc : count the number of words in a string• Words separated by white space: ' ', '\t', '\n'&c.

• Maybe we can count the number of white spaces in the string:wordc :: String -> Intwordc "" = 0wordc (d:ds)

| isSpace d = 1 + wordc ds| otherwise = wordc ds

• Not correct: wordc "abc d"will return 5

Suresh PRGH 2019: Lecture 8 September 4, 2019 16 / 19

Page 61: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Counting words

• wordc : count the number of words in a string• Words separated by white space: ' ', '\t', '\n'&c.• Maybe we can count the number of white spaces in the string:

wordc :: String -> Intwordc "" = 0wordc (d:ds)

| isSpace d = 1 + wordc ds| otherwise = wordc ds

• Not correct: wordc "abc d"will return 5

Suresh PRGH 2019: Lecture 8 September 4, 2019 16 / 19

Page 62: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Counting words

• wordc : count the number of words in a string• Words separated by white space: ' ', '\t', '\n'&c.• Maybe we can count the number of white spaces in the string:

wordc :: String -> Intwordc "" = 0wordc (d:ds)

| isSpace d = 1 + wordc ds| otherwise = wordc ds

• Not correct: wordc "abc d"will return 5

Suresh PRGH 2019: Lecture 8 September 4, 2019 16 / 19

Page 63: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Correct wordc

• Aword starts when previous character is a space and the current one isnot

• Add a space at the very beginning to apply same logic to first wordwordc :: String -> Intwordc s = go (' ':s)go [c] = 0go (c:d:ds)

| isSpace c && not (isSpace d)= 1 + go (d:ds)

| otherwise = go (d:ds)

Suresh PRGH 2019: Lecture 8 September 4, 2019 17 / 19

Page 64: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Correct wordc

• Aword starts when previous character is a space and the current one isnot• Add a space at the very beginning to apply same logic to first word

wordc :: String -> Intwordc s = go (' ':s)go [c] = 0go (c:d:ds)

| isSpace c && not (isSpace d)= 1 + go (d:ds)

| otherwise = go (d:ds)

Suresh PRGH 2019: Lecture 8 September 4, 2019 17 / 19

Page 65: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Tuples

• Keep multiple types of data together

• Student info: ("Suresh", 3170, "01/01/2000")

• List of marks in a course• [("Ashvini", 85), ("Bharani", 90), ("Krittika", 87)]

• (3, -21) :: (Int, Int)

• (13, True, 97) :: (Int, Bool, Int)

• ([1,2], "abcd") :: ([Int], String)

Suresh PRGH 2019: Lecture 8 September 4, 2019 18 / 19

Page 66: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Tuples

• Keep multiple types of data together• Student info: ("Suresh", 3170, "01/01/2000")

• List of marks in a course• [("Ashvini", 85), ("Bharani", 90), ("Krittika", 87)]

• (3, -21) :: (Int, Int)

• (13, True, 97) :: (Int, Bool, Int)

• ([1,2], "abcd") :: ([Int], String)

Suresh PRGH 2019: Lecture 8 September 4, 2019 18 / 19

Page 67: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Tuples

• Keep multiple types of data together• Student info: ("Suresh", 3170, "01/01/2000")

• List of marks in a course

• [("Ashvini", 85), ("Bharani", 90), ("Krittika", 87)]

• (3, -21) :: (Int, Int)

• (13, True, 97) :: (Int, Bool, Int)

• ([1,2], "abcd") :: ([Int], String)

Suresh PRGH 2019: Lecture 8 September 4, 2019 18 / 19

Page 68: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Tuples

• Keep multiple types of data together• Student info: ("Suresh", 3170, "01/01/2000")

• List of marks in a course• [("Ashvini", 85), ("Bharani", 90), ("Krittika", 87)]

• (3, -21) :: (Int, Int)

• (13, True, 97) :: (Int, Bool, Int)

• ([1,2], "abcd") :: ([Int], String)

Suresh PRGH 2019: Lecture 8 September 4, 2019 18 / 19

Page 69: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Tuples

• Keep multiple types of data together• Student info: ("Suresh", 3170, "01/01/2000")

• List of marks in a course• [("Ashvini", 85), ("Bharani", 90), ("Krittika", 87)]

• (3, -21) :: (Int, Int)

• (13, True, 97) :: (Int, Bool, Int)

• ([1,2], "abcd") :: ([Int], String)

Suresh PRGH 2019: Lecture 8 September 4, 2019 18 / 19

Page 70: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Tuples

• Keep multiple types of data together• Student info: ("Suresh", 3170, "01/01/2000")

• List of marks in a course• [("Ashvini", 85), ("Bharani", 90), ("Krittika", 87)]

• (3, -21) :: (Int, Int)

• (13, True, 97) :: (Int, Bool, Int)

• ([1,2], "abcd") :: ([Int], String)

Suresh PRGH 2019: Lecture 8 September 4, 2019 18 / 19

Page 71: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Tuples

• Keep multiple types of data together• Student info: ("Suresh", 3170, "01/01/2000")

• List of marks in a course• [("Ashvini", 85), ("Bharani", 90), ("Krittika", 87)]

• (3, -21) :: (Int, Int)

• (13, True, 97) :: (Int, Bool, Int)

• ([1,2], "abcd") :: ([Int], String)

Suresh PRGH 2019: Lecture 8 September 4, 2019 18 / 19

Page 72: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Marks list

• Amark list is a list of pairs

• Each pair consists of the student name and marks• lookup finds the marks obtained by a student:

type Marklist = [(String, Int)]lookup :: String -> Marklist -> Maybe Intlookup n [] = Nothinglookup n (name,marks):ml

| n == name = Just marks| otherwise = lookup n ml

Suresh PRGH 2019: Lecture 8 September 4, 2019 19 / 19

Page 73: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Marks list

• Amark list is a list of pairs• Each pair consists of the student name and marks

• lookup finds the marks obtained by a student:

type Marklist = [(String, Int)]lookup :: String -> Marklist -> Maybe Intlookup n [] = Nothinglookup n (name,marks):ml

| n == name = Just marks| otherwise = lookup n ml

Suresh PRGH 2019: Lecture 8 September 4, 2019 19 / 19

Page 74: Programming in Haskell: Lecture 8 · ProgramminginHaskell:Lecture8 SPSuresh September4,2019 Suresh PRGH2019:Lecture8 September4,2019 1/19

Example: Marks list

• Amark list is a list of pairs• Each pair consists of the student name and marks• lookup finds the marks obtained by a student:

type Marklist = [(String, Int)]lookup :: String -> Marklist -> Maybe Intlookup n [] = Nothinglookup n (name,marks):ml

| n == name = Just marks| otherwise = lookup n ml

Suresh PRGH 2019: Lecture 8 September 4, 2019 19 / 19