Martin Sulzmann
In the past:
Attend lectures (if you feel like it)
Do the exercises (if you feel like it)
The exam is coming up!
Memorize all past exam papers!
Don’t memorize exams — understand how exams are constructed.
Specific topic: Haskell functions
Copy and paste won’t work
Categories of exam-style questions
Further advice
Here are a few sample questions that cover the basics of functions in Haskell.
Let’s feed this to some AI.
Prompt.
Hi there, below are some simple Haskell questions (covering basic functions in Haskell). Could you generate a few similar questions. Thanks.
Here’s a possible answer.
Here are a few more practice questions following the style and topics of your examples:
-- QUESTION. Define a function multiply using a lambda expression.
-- ANSWER.
multiply = \x -> \y -> x * y
-- QUESTION. Simplify the following expression by removing unnecessary parentheses.
-- val = ((multiply 2) (add 3 4))
-- ANSWER.
val = multiply 2 (add 3 4)
-- QUESTION. Implement a function triple by partially applying the multiply function.
-- ANSWER.
triple = multiply 3
-- QUESTION. True or false: The type of the plus function below is Int -> Int -> Int.
-- plus (x, y) = x + y
-- ANSWER.
False. The type is (Int, Int) -> Int because it takes a single tuple as an argument, not two separate arguments.
-- QUESTION. Use sections (e.g., (2+)) to rewrite the following list transformation without using a lambda or the add function.
-- ex4 = map (\x -> x * 10) [1, 2, 3]
-- ANSWER.
ex4' = map (*10) [1, 2, 3]
-- QUESTION. True or false: In Haskell, functions are "First-class citizens."
-- ANSWER.
True. This means functions can be passed as arguments, returned as values, and stored in data structures.
-- QUESTION. Is the following function pure or impure?
-- randomAdd x = x + (length "hello")
-- ANSWER.
Pure. Even though it uses a string literal, for any given x, the output will always be the same and it has no side effects.
And some examples of follow-up questions.
Prompt.
What does "first-class" mean? What would be first class in say Java?
Yields (in my case)
An entity is "first-class" in a programming language
if it can be treated like any other basic value (such as an integer or a string).
What "First-Class" Means
According to the classic definition from Structure and Interpretation of Computer Programs, a first-class citizen must be able to:
Be assigned to a variable or named by one.
Be passed as an argument to a function or procedure.
Be returned as the result of a function or procedure.
Be stored in data structures, such as lists, maps, or arrays.
and lots of more info.
The trick is to stay focussed.
Prompt.
So I understand Java and OO quite well. Could you me a "first-class" example in Java that involves objects?
Yields (in my case)
Since
Objects are the primary first-class citizens in Java, a "first-class" example is simply any scenario where an object is treated as a standard piece of data.
Here is a classic example using a Comparator object. Notice how the object descendingOrder is treated exactly like a variable—passed, stored, and moved around.
import java.util.*;
public class FirstClassExample {
public static void main(String[] args) {
// 1. Assigned to a variable
Comparator<Integer> descendingOrder = (a, b) -> b - a;
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5);
// 2. Passed as an argument to a method (sort)
Collections.sort(numbers, descendingOrder);
// 3. Stored in a data structure
List<Comparator<Integer>> strategies = new ArrayList<>();
strategies.add(descendingOrder);
// 4. Returned from a method
Comparator<Integer> myStrategy = getMyComparator();
}
public static Comparator<Integer> getMyComparator() {
return (a, b) -> a - b; // Returning an object
}
}Why this matters
In older languages (like C or early Java), you couldn't easily pass "behavior" around. You had to wrap it in a class structure. In Haskell, you do the exact same thing as the example above, but you don't need the Comparator interface or the class wrapper—the function itself is the first-class object.
Would you like to see the Haskell equivalent of this Java code to see how the syntax differs?
Next prompt.
Yes please.
Yields (in my case)
In Haskell, you don't need to wrap the logic in a
Comparator class or a Functional Interface. The function itself is the data.
Here is the direct equivalent of the Java example. Notice how we treat the descending function exactly like the numbers list.
import Data.List (sortBy)
-- 1. Assigned to a variable (named)
descending x y = compare y x
main :: IO ()
main = do
let numbers = [3, 1, 4, 1, 5]
-- 2. Passed as an argument (to sortBy)
let sortedNums = sortBy descending numbers
-- 3. Stored in a data structure (a list of functions!)
-- Each function in this list takes two Ints and returns an Ordering
let strategies = [descending, compare]
-- 4. Returned from a function (calling getStrategy returns a function)
let myStrategy = getStrategy True
print (sortBy myStrategy numbers)
-- A function that returns another function
getStrategy :: Bool -> (Int -> Int -> Ordering)
getStrategy useDesc = if useDesc then descending else compareKey Differences to Spot:
No "Wrappers": In Java, you passed a Comparator object that happened to have a method. In Haskell, you pass the function itself.
Type Signatures: The type (Int -> Int -> Ordering) is a first-class type. You can use it anywhere you'd use Int or String.
Higher-Order Functions: Functions like sortBy are called "higher-order" because they accept other functions as parameters—this is only possible because functions are first-class.
and so on …
Prompt.
Here's a link to some Haskell lecture notes: https://sulzmann.github.io/ProgrammingParadigms/pp-haskell.html
What could possible exam questions look like derived from these notes?
Yields (in my case)
Based on the lecture notes, exam questions likely focus on core Haskell mechanics, including type inference, pattern matching, recursion, and higher-order functions like folds [1]. Additional questions may cover list comprehensions, lazy evaluation concepts, and user-defined algebraic data types [1]. For more details, visit the lecture notes at sulzmann.github.io.
Based on the lecture notes we can identify the following categories of exam-style questions.
Identify these categories yourself. Ask the instructor or use some AI.
The notes emphasize that “Every expression has a type.” A common exam task is manually inferring the most general type.
QUESTION. Given the following function definition, what is its most general type signature?
ANSWER: f :: Bool -> a -> a -> a
WHY: x must be Bool for the if condition. y and z must be the same type a because the branches of an if must match.
The notes use length and sum as
foundational examples. Students should be able to transform “English
logic” into recursive patterns.
QUESTION: Write a recursive function myCount that counts how many times a specific element appears in a list. Do not use built-in filter functions.
ANSWER:
myCount _ [] = 0
myCount target (x:xs)
| x == target = 1 + myCount target xs
| otherwise = myCount target xsQUESTION. What’s the type of myCount?
Since the notes cover map, filter, and
partial application, an exam will likely test if they understand that
f x y is actually (f x) y.
QUESTION: Rewrite the following expression using only partial
application and the . (composition) operator. Remove the explicit
parameter xs.
ANSWER: process = map (+1) . filter (>5)
"I am a student studying these Haskell notes [Link]. Act as a strict TA. Give me a 3-question quiz: one on List Comprehensions, one on Lazy Evaluation, and one on Type Classes. Don't give me the answers until I submit my code for you to grade."
Work in progress