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.
w :: Maybe Int
= Just 3
w
x :: Maybe String
= Just "hello"
x
y :: Maybe Char
= Nothing
y
z :: Maybe (Maybe Int)
= Just Nothing
z
safeDiv :: Integer -> Integer -> Maybe Integer
0 = Nothing
safeDiv _ = Just (x `div` y)
safeDiv x y
showDiv :: Integer -> Integer -> String
= case safeDiv x y of
showDiv x y Nothing -> "Division by zero"
Just z -> "Result is " ++ show z
Give two example values of type Maybe Bool
.
How many distinct values of type Maybe (Maybe Bool)
are there? List all of them.
How is safeDiv
different from
div
?
Try showDiv
on some examples. Describe in words what
it does.
What does the a
in the definition of
Maybe
represent?
If you know Java, 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.
(You know the
drill) You should be prepared to share your version of
plusMaybe
with another group.
ROTATE ROLES
ints :: [Integer]
= [3, 5, 92]
ints
noInts :: [Integer]
= []
noInts
moreInts :: [Integer]
= 7 : ints
moreInts
yetMoreInts :: [Integer]
= 4 : 2 : ints
yetMoreInts
someInts :: [Integer]
= 8 : 42 : noInts
someInts
ints2 :: [Integer]
= 3 : 5 : 92 : [] ints2
Evaluate length ints
and
length noInts
.
Explain what []
means.
Evaluate moreInts
and
length moreInts
.
Do the same for yetMoreInts
.
Now evaluate ints
. Has it changed?
Write an expression e
such that
length e
evaluates to 6
.
Explain what the (:)
operator does.
What will someInts
evaluate to? How about
length someInts
? Write down your guesses before
typing them into GHCi.
Now check your guesses.
Evaluate ints2
. What do you notice?
ROTATE ROLES
greeting :: String
= "Hello"
greeting
greeting2 :: String
= ['H','e','l','l','o']
greeting2
greeting3 :: [Char]
= ['H','e','l','l','o']
greeting3
everyone :: String
= "world" everyone
Evaluate greeting
, greeting2
, and
greeting3
. What differences do you notice? What can you
conclude? (Hint: try typing :info String
at the GHCi
prompt.)
Try evaluating greeting : everyone
. What
happens?
Now try evaluating greeting ++ everyone
. What
happens?
Explain the difference between (:)
and
(++)
.
What are the types of (:)
and (++)
(note: you must enter :type (:)
and
:type (++)
, not e.g. :type ++
)? Do
they match your explanation above?
Explain the difference between 'a'
and
"a"
.
Write an expression using greeting
and
everyone
which evaluates to
"Hello, world!"
.
ROTATE ROLES
= 0 :: Integer
listLength [] :xs) = 1 + listLength xs
listLength (_
startsWith :: String -> String -> Bool
= undefined
startsWith [] _ :_) [] = undefined
startsWith (_:xs) (y:ys) = undefined startsWith (x
What is the type of listLength
? (Feel free to ask
GHCi.)
The type of listLength
probably has a lowercase
letter in it, like t
or a
. Explain what the
type of listLength
means.
Evaluate startsWith "cat" "catastrophe"
. What
happens?
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 "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 "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 [] -> []
listReverse [1,2,3] -> [3,2,1]
listReverse "Hello" -> "olleH"
DO NOT look at any existing implementation of reverse.