Control structures in Haskell programming provide a foundation for decision-making, pattern matching, and iterative processing through recursion and list comprehensions. Learning to effectively use conditional expressions, pattern matching, and recursion enables functional programmers to create efficient and readable code. Explore these concepts with 30 multiple-choice questions designed to enhance your Haskell expertise.
MCQs on Control Structures in Haskell
Conditional Expressions (if, else, guard)
What is the correct syntax for an if expression in Haskell?
a) if condition then expr1 else expr2
b) if condition { expr1 } else { expr2 }
c) if (condition) { expr1 } else { expr2 }
d) if (condition): expr1 else: expr2
What type must the then and else expressions have in an if expression?
a) They can have different types.
b) They must be functions.
c) They must have the same type.
d) They must return integers.
What happens if the else branch is missing in an if expression?
a) It throws a compile-time error.
b) It defaults to Nothing.
c) It defaults to () (unit).
d) The program crashes at runtime.
Which construct in Haskell is equivalent to multiple if-else conditions?
a) Pattern matching
b) Guards
c) Lambda functions
d) Case expressions
In guards, what operator is used to define a condition?
a) =
b) <-
c) |
d) ->
How are guards evaluated in a function definition?
a) From bottom to top
b) In random order
c) From top to bottom
d) Based on priority
Which is the correct guard for a function to check if a number is positive?
a) | x > 0 = True
b) if x > 0 then True
c) -> x > 0 = True
d) : x > 0 = True
Pattern Matching (with case and function clauses)
What is pattern matching primarily used for in Haskell?
a) Iterating through lists
b) Decomposing data structures
c) Validating conditions
d) Writing loops
Which keyword is used for pattern matching in Haskell?
a) match
b) case
c) switch
d) guard
How does pattern matching handle unmatched cases?
a) It returns Nothing.
b) It throws a runtime error.
c) It evaluates to () (unit).
d) It retries with the last case.
What does the wildcard _ signify in pattern matching?
a) Match any value without binding it.
b) Match specific values.
c) Exclude certain values.
d) A special constant.
How can you match the head and tail of a list in Haskell?
a) x : xs
b) x -> xs
c) head x, tail xs
d) [x | xs]
What is the result of case [1, 2, 3] of [] -> "Empty"; x:xs -> "Non-empty"?
a) "Empty"
b) "Non-empty"
c) Runtime error
d) "1"
Which function clause will correctly match an empty list?
a) myFunc [x] = ...
b) myFunc [] = ...
c) myFunc x:xs = ...
d) myFunc [x:xs] = ...
How can you explicitly specify all unmatched cases in a case expression?
a) Using _ as the last pattern
b) Adding an else branch
c) Using a guard condition
d) Declaring default
Recursion: Base Case, Recursive Case, and Termination
What is the base case in recursion?
a) The part where recursion stops
b) The part where the function calls itself
c) A loop in functional programming
d) A condition that triggers infinite recursion
What happens if a recursive function does not include a base case?
a) It throws a compile-time error.
b) It causes infinite recursion.
c) It returns Nothing.
d) It automatically stops after 10 iterations.
Which of the following is an example of a recursive function?
a) factorial n = if n == 0 then 1 else n * factorial (n - 1)
b) factorial n = n * 2
c) factorial n = n + 1
d) factorial n = map (*n) [1..n]
What is the key property of tail-recursive functions?
a) They use constant stack space.
b) They cannot return values.
c) They are more readable.
d) They only handle numeric data.
How do you terminate a recursive function in Haskell?
a) Return a base case value.
b) Use break.
c) Use stop.
d) Declare it as main.
List Comprehensions
What is the primary purpose of list comprehensions in Haskell?
a) Filtering and transforming lists
b) Performing string concatenations
c) Implementing loops
d) Matching patterns
Which symbol is used to define a generator in a list comprehension?
a) <-
b) ->
c) :
d) =
What is the result of [x*2 | x <- [1, 2, 3]]?
a) [2, 4, 6]
b) [1, 2, 3]
c) [4, 8, 12]
d) [3, 6, 9]
How can you filter elements in a list comprehension?
a) By adding a condition after the generator
b) By using case expressions
c) By using if expressions only
d) By applying map
What does [x | x <- [1, 2, 3], x > 2] return?
a) [3]
b) [1, 2, 3]
c) [2, 3]
d) []
Which keyword is used in list comprehensions to combine multiple generators?
a) and
b) let
c) then
d) None, multiple generators are separated by commas.
What does [x + y | x <- [1, 2], y <- [3, 4]] return?
a) [4, 5, 5, 6]
b) [3, 4, 5, 6]
c) [4, 5]
d) [1, 2, 3, 4]
Can list comprehensions in Haskell be nested?
a) Yes
b) No
Which of the following is NOT true about list comprehensions?
a) They can work with infinite lists.
b) They cannot use conditional filtering.
c) They are a declarative way of generating lists.
d) They support multiple generators.
What is a common use case for list comprehensions in Haskell?
a) Generating prime numbers
b) Filtering a list
c) Transforming lists
d) All of the above
Here are the answers to the MCQs on Control Structures in Haskell:
Qno
Answer
1
a) if condition then expr1 else expr2
2
c) They must have the same type
3
a) It throws a compile-time error
4
b) Guards
5
c) `
6
c) From top to bottom
7
a) `
8
b) Decomposing data structures
9
b) case
10
b) It throws a runtime error
11
a) Match any value without binding it
12
a) x : xs
13
b) "Non-empty"
14
b) myFunc [] = ...
15
a) Using _ as the last pattern
16
a) The part where recursion stops
17
b) It causes infinite recursion
18
a) factorial n = if n == 0 then 1 else n * factorial (n - 1)
19
a) They use constant stack space
20
a) Return a base case value
21
a) Filtering and transforming lists
22
a) <-
23
a) [2, 4, 6]
24
a) By adding a condition after the generator
25
a) [3]
26
d) None, multiple generators are separated by commas