In this module we will complete our initial exploration of the Haskell programming language. For today, choose whoever you wish to start as the driver.
data Maybe a where Nothing :: Maybe a Just :: a -> Maybe a
Note that the above definition of Maybe does not have bird tracks in front of it since it is already defined in the standard library; I just wanted to show you its definition.
Maybe
w :: Maybe Int w = Just 3 x :: Maybe String x = Just "hello" y :: Maybe Char y = Nothing z :: Maybe (Maybe Int) z = Just Nothing safeDiv :: Integer -> Integer -> Maybe Integer safeDiv _ 0 = Nothing safeDiv x y = Just (x `div` y) showDiv :: Integer -> Integer -> String showDiv x y = case safeDiv x y of Nothing -> "Division by zero" Just z -> "Result is " ++ show z
Give two example values of type Maybe Bool.
Maybe Bool
How many distinct values of type Maybe (Maybe Bool) are there? List all of them.
Maybe (Maybe Bool)
How is safeDiv different from div?
safeDiv
div
Try showDiv on some examples. Describe in words what it does.
showDiv
What does the a in the definition of Maybe represent?
a
What Java feature does the a remind you of?
Write a function plusMaybe :: Maybe Integer -> Maybe Integer -> Maybe Integer which performs addition if both arguments are Just, and returns Nothing otherwise.
plusMaybe :: Maybe Integer -> Maybe Integer -> Maybe Integer
Just
Nothing
(You know the drill) You should be prepared to share your version of plusMaybe with another group.
plusMaybe
ROTATE ROLES
ints :: [Integer] ints = [3, 5, 92] noInts :: [Integer] noInts = [] moreInts :: [Integer] moreInts = 7 : ints yetMoreInts :: [Integer] yetMoreInts = 4 : 2 : ints someInts :: [Integer] someInts = 8 : 42 : noInts ints2 :: [Integer] ints2 = 3 : 5 : 92 : []
Evaluate length ints and length noInts.
length ints
length noInts
Explain what [] means.
[]
Evaluate moreInts and length moreInts.
moreInts
length moreInts
Do the same for yetMoreInts.
yetMoreInts
Now evaluate ints. Has it changed?
ints
Write an expression e such that length e evaluates to 6.
e
length e
6
Explain what the (:) operator does.
(:)
What will someInts evaluate to? How about length someInts? Write down your guesses before typing them into GHCi.
someInts
length someInts
Now check your guesses.
Evaluate ints2. What do you notice?
ints2
greeting :: String greeting = "Hello" greeting2 :: String greeting2 = ['H','e','l','l','o'] greeting3 :: [Char] greeting3 = ['H','e','l','l','o'] everyone :: String everyone = "world"
Evaluate greeting, greeting2, and greeting3. What differences do you notice? What can you conclude? (Hint: try typing :info String at the GHCi prompt.)
greeting
greeting2
greeting3
:info String
Try evaluating greeting : everyone. What happens?
greeting : everyone
Now try evaluating greeting ++ everyone. What happens?
greeting ++ everyone
Explain the difference between (:) and (++).
(++)
What are the types of (:) and (++)? Do they match your explanation above?
Explain the difference between 'a' and "a".
'a'
"a"
Write an expression using greeting and everyone which evaluates to "Hello, world!".
everyone
"Hello, world!"
listLength [] = 0 :: Integer listLength (_:xs) = 1 + listLength xs startsWith :: String -> String -> Bool startsWith [] _ = undefined startsWith (_:_) [] = undefined startsWith (x:xs) (y:ys) = undefined
What is the type of listLength? (Feel free to ask GHCi.)
listLength
The type of listLength probably has a lowercase letter in it, like t or a. Explain what the type of listLength means.
t
Evaluate startsWith "cat" "catastrophe". What happens?
startsWith "cat" "catastrophe"
Complete the definition of startsWith by replacing undefined with appropriate expressions. startsWith should test whether the second argument has the first argument as a prefix. For example:
startsWith
undefined
startsWith "cat" "catastrophe" -> True startsWith "car" "catastrophe" -> False startsWith "ban" "banana" -> True startsWith "" "dog" -> True startsWith "at" "catastrophe" -> False startsWith "dog" "" -> False
Write a function contains :: String -> String -> Bool, which tests whether the second argument contains the first argument as a (contiguous) substring. For example,
contains :: String -> String -> Bool
contains "cat" "catastrophe" -> True contains "cat" "concatenate" -> True contains "cat" "create" -> False contains "fly" "old lady" -> False
Hint: use startsWith.
Write a function listReverse :: [a] -> [a] which reverses a list. For example,
listReverse :: [a] -> [a]
listReverse [] -> [] listReverse [1,2,3] -> [3,2,1] listReverse "Hello" -> "olleH"
DO NOT look at any existing implementation of reverse.