The lib Package#

This is the core standard library for Functional Java. It contains a selection of data types and functions that are useful in many programming scenarios. To import this package, use the following import statements:

import comp1110.lib.*;
import comp1110.lib.Date;
import static comp1110.lib.Functions.*;

General#

Records#

Pair

Pair#
/**
 * Represents a pair of two values of given types.
 * Examples:
 * - Pair(5, "Hello")
 * - Pair(16.0, 32.5)
 * - Pair(Pair("", true), 0)
 * @param first The first value in the pair
 * @param second The second value in the pair
 */
record Pair<S, T>(
    S first,
    T second) {}
// TEMPLATE:
// { ... pair.first() ... pair.second() ... }

Itemizations#

Maybe

Maybe#
/**
 * Represents a value that may or may not be present.
 * It is one of:
 * - Nothing, where no value is present
 * - Something, where some value is present
 */
sealed interface Maybe<T>permits Nothing, Something{}

// TEMPLATE:
// {
//     ...
//     return ... switch(maybe) {
//         case Nothing<T>() ->  ... ;
//         case Something<T>(var element) -> 
//              ... element ... ;
//     } ...;
// }

/**
 * Represents the absence of a value
 * Examples:
 * - Nothing<T>()
 */
record Nothing<T>(
) implements Maybe<T>{}
/**
 * Represents the presence of a value of type T
 * Examples:
 * - Something<Integer>(5)
 * - Something<String>("Hello")
 * @param element The value that is present
 */
record Something<T>(
    T element) implements Maybe<T>{}

Functions#

GetVersion ; CheckVersion ; DefaultCaseError ; Equals ; Compare ; Min ; Max ; GreaterThan ; LessThan ; ToString ; IsIntString ; StringToInt ; IsLongString ; StringToLong ; IsFloatString ; StringToFloat ; IsDoubleString ; StringToDouble ; StringToBoolean ; Length ; RandomNumber ; Default ; Join

GetVersion#
/** 
 * Returns the current version of the COMP1110 Standard Library
 *
 * Examples:
 * given: 
 *  expect: "2025S1-1"
 * given: 
 *  expect: "2025S1-2"
 * @return the current version of the COMP1110 Standard Library
 */
String GetVersion();
CheckVersion#
/** 
 * Checks the compatibility of the used library
 * with a particular version.
 * Throws an exception if not compatible.
 *
 * Examples:
 * given: "2025S1-1"
 *  expect: the program continues normally,
 *          except if breaking changes have been made to the library
 * given: "foobar"
 *  expect: the program will show an error message and exit
 *
 * @param version The required version of the library
 */
void CheckVersion(String version);
DefaultCaseError#
/** 
 * Use this to end the program if are doing a case distinction
 * that requires a default case which you know to be
 * impossible (under given preconditions and invariants).
 * The program will display an error message.
 * The function nominally returns a value of any type you ask
 * for, even though it never will.
 *
 * Examples:
 * given: (nothing)
 *  expect: The program ends with an error message
 *
 * @param message A message to display when the program ends.
 *          This is in addition to generic information about the
 *          kind and location of the error.
 *        OPTIONAL, default = ""
 */
<T> T DefaultCaseError(String message);
Equals#
/** 
 * Returns whether two given values are equal
 *
 * Examples:
 * given: "Hello", "World"
 *  expect: false
 * given: "COMP", "COMP"
 *  expect: true
 * given: 42, 42
 *  expect: true
 *
 * @param o1 the first value to be compared
 * @param o2 the second value to be compared
 * @return true if the values are equal, false if not
 */
boolean Equals(Object o1, Object o2);
Compare#
/** 
 * Compares two values of a comparable type T.
 * Comparable Types are:
 *   - String
 *   - the number types (int, double, ...)
 *   - booleans
 *   - Date
 *   - DateTime
 *
 * Examples:
 * given: 5, 3
 *  expect: A positive integer
 * given: "Alpha", "Omega"
 *  expect: A negative integer
 * given: true, true
 *  expect: 0
 *
 * @param left the first value to compare
 * @param right the second value to compare
 * @return A negative integer if left < right
 *         A positive integer if left > right
 *         0 if left equals right
 */
<T> int Compare(T left, T right);
Min#
/** 
 * Returns the smaller of two given values of
 * a comparable type T.
 * Comparable Types are:
 *   - String
 *   - the number types (int, double, ...)
 *   - booleans
 *   - Date
 *   - DateTime
 *
 * Examples:
 * given: 5, 3
 *  expect: 3
 * given: "Alpha", "Omega"
 *  expect: "Alpha"
 * given: true, true
 *  expect: true
 *
 * @param left the first value to compare
 * @param right the second value to compare
 * @return The smaller value, or the left argument
 *         if they are equal.
 */
<T> T Min(T left, T right);
Max#
/** 
 * Returns the larger of two given values of
 * a comparable type T.
 * Comparable Types are:
 *   - String
 *   - the number types (int, double, ...)
 *   - booleans
 *   - Date
 *   - DateTime
 *
 * Examples:
 * given: 5, 3
 *  expect: 5
 * given: "Alpha", "Omega"
 *  expect: "Omega"
 * given: true, true
 *  expect: true
 *
 * @param left the first value to compare
 * @param right the second value to compare
 * @return The larger value, or the left argument
 *         if they are equal.
 */
<T> T Max(T left, T right);
GreaterThan#
/** 
 * Checks whether a comparable value is greater than another
 * Comparable Types are:
 *   - String
 *   - the number types (int, double, ...)
 *   - booleans
 *   - Date
 *   - DateTime
 *
 * Examples:
 * given: 5, 3
 *  expect: true
 * given: "Alpha", "Omega"
 *  expect: false
 * given: true, true
 *  expect: false
 *
 * @param greater the potentially greater value
 * @param smaller the potentially smaller value
 * @return True if greater > smaller, false if not
 */
<T> boolean GreaterThan(T greater, T smaller);
LessThan#
/** 
 * Checks whether a comparable value is less than another
 * Comparable Types are:
 *   - String
 *   - the number types (int, double, ...)
 *   - booleans
 *   - Date
 *   - DateTime
 *
 * Examples:
 * given: 5, 3
 *  expect: false
 * given: "Alpha", "Omega"
 *  expect: true
 * given: true, true
 *  expect: false
 *
 * @param smaller the potentially smaller value
 * @param greater the potentially greater value
 * @return True if smaller < greater, false if not
 */
<T> boolean LessThan(T smaller, T greater);
ToString#
/** 
 * Returns a String representation of a given value
 *
 * Examples:
 * given: 5
 *  expect: "5"
 * given: "Hello"
 *  expect: "Hello"
 * given: A Date representing 2025-02-18
 *  expect: "2025-02-18"
 *
 * @param o Any value
 * @return A String representation of the given value
 */
String ToString(Object o);
IsIntString#
/** 
 * Checks whether a String represents an int
 *
 * Examples:
 * given: 15
 *  expect: true
 * given: Hello
 *  expect: false
 *
 * @param str The String that may represent an int
 * @return true if the String represents an int, false if not
 */
boolean IsIntString(String str);
StringToInt#
/** 
 * Converts a String to an Integer.
 *
 * Examples:
 * given: "-15"
 *  expect: -15
 * given: "1337"
 *  expect: 1337
 *
 * @param str The String representing an Integer
 * @return The Integer represented by the String
 * @implSpec
 *   Precondition: The given String must represent an Integer.
 */
int StringToInt(String str);
IsLongString#
/** 
 * Checks whether a String represents a long
 *
 * Examples:
 * given: 15
 *  expect: true
 * given: Hello
 *  expect: false
 *
 * @param str The String that may represent a long
 * @return true if the String represents a long, false if not
 */
boolean IsLongString(String str);
StringToLong#
/** 
 * Converts a String to a Long.
 *
 * Examples:
 * given: "-15"
 *  expect: -15
 * given: "1337"
 *  expect: 1337
 *
 * @param str The String representing a Long
 * @return The Long represented by the String
 * @implSpec
 *   Precondition: The given String must represent a Long.
 */
long StringToLong(String str);
IsFloatString#
/** 
 * Checks whether a String represents a float
 *
 * Examples:
 * given: 15.0
 *  expect: true
 * given: Hello
 *  expect: false
 *
 * @param str The String that may represent a float
 * @return true if the String represents a float, false if not
 */
boolean IsFloatString(String str);
StringToFloat#
/** 
 * Converts a String to a Float.
 *
 * Examples:
 * given: "-15.0"
 *  expect: -15.0f
 * given: "1337.3"
 *  expect: 1337.3f
 *
 * @param str The String representing a Float
 * @return The Float represented by the String
 * @implSpec
 *   Precondition: The given String must represent a Float.
 */
float StringToFloat(String str);
IsDoubleString#
/** 
 * Checks whether a String represents a double
 *
 * Examples:
 * given: 15.0
 *  expect: true
 * given: Hello
 *  expect: false
 *
 * @param str The String that may represent a double
 * @return true if the String represents a double, false if not
 */
boolean IsDoubleString(String str);
StringToDouble#
/** 
 * Converts a String to a Double.
 *
 * Examples:
 * given: "-15.0"
 *  expect: -15.0
 * given: "1337.3"
 *  expect: 1337.3
 *
 * @param str The String representing a Double
 * @return The Double represented by the String
 * @implSpec
 *   Precondition: The given String must represent a Double.
 */
double StringToDouble(String str);
StringToBoolean#
/** 
 * Converts a String to a Boolean.
 *
 * Examples:
 * given: "true"
 *  expect: true
 * given: "false"
 *  expect: false
 *
 * @param str The String representing a Boolean
 * @return The Boolean represented by the String
 * @implSpec
 *   Precondition: The given String must represent an Boolean.
 */
boolean StringToBoolean(String str);
Length#
/** 
 * Returns the length of an Array
 *
 * Examples:
 * given: {}
 *  expect: 0
 * given: {1,2,3,4,5}
 *  expect: 5
 *
 * @param arr The Array whose length we want to determine
 * @return The length of the Array
 */
<T> int Length(T[] arr);
RandomNumber#
/** 
 * Returns a random number
 *
 * Examples:
 * given: 5, 100
 *  expect: a number between 5 (inclusive) and 100 (exclusive)
 * given: 100
 *  expect: a number between 0 (inclusive) and 100 (exclusive)
 * given: (no arguments)
 *  expect: any integer between 2^(-31) and (2^31)-1
 *
 * @param min The minimum number to return (>= 0)
 *        OPTIONAL, default = 0 if max given, else Integer.MIN_VALUE
 * @param max The exclusive upper bound for the random
 *          number. If only one argument is specified,
 *          it counts for this argument. (>= 0)
 *        OPTIONAL, default = Integer.MAX_VALUE (around 2 billion)
 * @return A random integer between the specified bounds
 */
int RandomNumber(int min, int max);
Default#
/** 
 * Returns either the value contained in a Something case
 * of a Maybe value, or the default value if the Maybe
 * value is Nothing()
 *
 * Examples:
 * given: Something(50), 100
 *  expect: 50
 * given: Nothing(), 100
 *  expect: 100
 *
 * @param maybe The Maybe-value whose content we want to extract
 * @param else The default value to use if maybe is Nothing
 */
<T> T Default(Maybe<T> maybe, T else);
Join#
/** 
 * Flattens levels of Maybes. If both outer levels are Something,
 * then returns the inner Something. Else returns Nothing.
 *
 * Examples:
 * given: Something(Something(50))
 *  expect: Something(50)
 * given: Something(Nothing())
 *  expect: Nothing()
 * given: Nothing()
 *  expect: Nothing()
 *
 * @param maybe The Maybe-value that we want to flatten
 */
<T> Maybe<T> Join(Maybe<Maybe<T>> maybe);

DateTime#

Opaque Data Types#

Date ; DateTime

Date#
/**
 * This type represents calendar dates.
 * Dates are associated with a timezone, by default
 * the local timezone, and represent some time at a
 * particular date. Use the functions further below
 * to create and compute with Dates.
 */
// This is an opaque type whose definition does not matter to you
DateTime#
/**
 * This type represents time/date combinations.
 * DateTimes are associated with a timezone, by default
 * the local timezone, and can also be used whereever
 * Date values are expected. Use the functions further
 * below to create and compute with DateTimes.
 */
// This is an opaque type whose definition does not matter to you

Functions#

CurrentDate ; CurrentTime ; IsDateValid ; GetDate ; GetDateTime ; GetYear ; GetMonth ; GetDay ; GetDayOfWeek ; GetHour ; GetMinute ; GetSecond ; GetMillisecond ; GetTimeZone ; AddYears ; AddMonths ; AddDays ; AddHours ; AddMinutes ; AddSeconds ; AddMilliseconds ; WithTimeZone ; InTimeZone ; ToDate ; YearsBetween ; MonthsBetween ; DaysBetween ; HoursBetween ; MinutesBetween ; SecondsBetween ; MillisecondsBetween ; FormatDate ; ParseDate ; ParseDateTime

CurrentDate#
/** 
 * Returns the current Date
 *
 * Examples:
 * given: "Australia/Sydney" at 2025-02-16 19:00 UTC
 *  expect: [2025-02-17, 00:00:00.000+11:00@Australia/Sydney]
 * given: "America/New_York" at 2025-02-16 02:00 UTC
 *  expect: [2025-02-15, 00:00:00.000-05:00@America/New_York]
 *
 * @param timeZone A time zone descriptor, such as Australia/Sydney
 *        OPTIONAL, default = The system's local timezone
 * @return The current date in the given time zone
 */
Date CurrentDate(String timeZone);
CurrentTime#
/** 
 * Returns the current Time and Date
 *
 * Examples:
 * given: "Australia/Sydney" at 2025-02-16 19:00:00.000 UTC
 *  expect: [2025-02-17, 06:00:00.000+11:00@Australia/Sydney]
 * given: "America/New_York" at 2025-02-16 02:00:00.000 UTC
 *  expect: [2025-02-15, 21:00:00.000-05:00@America/New_York]
 *
 * @param timeZone A time zone descriptor, such as Australia/Sydney
 *        OPTIONAL, default = The system's local timezone
 * @return The current time and date in the given time zone
 */
DateTime CurrentTime(String timeZone);
IsDateValid#
/** 
 * Checks whether a particular date is valid
 *
 * Examples:
 * given: 2025, 1, 17
 *  expect: true
 * given: 2025, 2, 29, "Australia/Sydney"
 *  expect: false
 * given: 2025, 11, 31
 *  expect: false
 *
 * @param year The year
 * @param month The month
 * @param day The day of the month
 * @param timeZone The zime zone of the date
 *        OPTIONAL, default = The system's local time zone
 * @return True if the month/day combination is valid
 *         for the year, false if not
 */
boolean IsDateValid(int year, int month, int day, String timeZone);
GetDate#
/** 
 * Constructs a Date value for a particular date
 *
 * Examples:
 * given: 2025, 1, 17
 *  expect: [2025-02-17, 00:00:00.000+-XX:XX@XXX]
 *          XX:XX@XXX depending on your system's local time zone
 * given: 2025, 1, 18, "Australia/Sydney"
 *  expect: [2025-01-18, 00:00:00.000+11:00@Australia/Sydney]
 *
 * @param year The year
 * @param month The month
 * @param day The day of the month
 * @param timeZone The zime zone of the date
 *        OPTIONAL, default = The system's local time zone
 * @return A Date representing the start of the specified
 *         day in the specified time zone
 */
Date GetDate(int year, int month, int day, String timeZone);
GetDateTime#
/** 
 * Constructs a DateTime value for a particular date and time
 *
 * Examples:
 * given: 2025, 1, 17, 15, 20, 0
 *  expect: [2025-02-17, 15:20:00.000+-XX:XX@XXX]
 *          XX:XX@XXX depending on your system's local time zone
 * given: 2025, 1, 18, 5, 45, 13, 253"Australia/Sydney"
 *  expect: [2025-01-18, 05:45:13.253+11:00@Australia/Sydney]
 *
 * @param year The year
 * @param month The month
 * @param day The day of the month
 * @param hour The hour of the day
 * @param minute The minute of the hour
 * @param second The second of the minute
 * @param millisecond The millisecond of the second
 *        OPTIONAL, default = 0
 * @param timeZone The zime zone of the date and time
 *        OPTIONAL, default = The system's local time zone
 * @return A DateTime representing the specified point in time
 */
DateTime GetDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, String timeZone);
GetYear#
/** 
 * Returns the year of a Date or DateTime value
 *
 * Examples:
 * given: [2025-05-13 ...]
 *  expect: 2025
 * given: [1925-01-14 ...]
 *  expect: 1925
 *
 * @param date The given date
 * @return The year of the given date
 */
int GetYear(Date date);
GetMonth#
/** 
 * Returns the month of a Date or DateTime value
 *
 * Examples:
 * given: [2025-05-13 ...]
 *  expect: 5
 * given: [1925-01-14 ...]
 *  expect: 1
 *
 * @param date The given date
 * @return The month of the given date
 */
int GetMonth(Date date);
GetDay#
/** 
 * Returns the day of a Date or DateTime value
 *
 * Examples:
 * given: [2025-05-13 ...]
 *  expect: 13
 * given: [1925-01-14 ...]
 *  expect: 14
 *
 * @param date The given date
 * @return The day of the given date
 */
int GetDay(Date date);
GetDayOfWeek#
/** 
 * Returns the day of the week of a Date or DateTime value
 * Monday is represented as 1, Sunday is represented as 7
 *
 * Examples:
 * given: [2025-05-13 ...]
 *  expect: 2
 * given: [1925-01-14 ...]
 *  expect: 3
 *
 * @param date The given date
 * @return The day of the week of the given date
 * @implSpec
 *   Postcondition: The returned value is between 1 and 7 (inclusive)
 */
int GetDayOfWeek(Date date);
GetHour#
/** 
 * Returns the hour of a DateTime value
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@...]
 *  expect: 22
 * given: [1925-01-14 06:47:01.003+11:00@...]
 *  expect: 6
 *
 * @param dateTime The given DateTime
 * @return The hour of the given DateTime
 */
int GetHour(DateTime dateTime);
GetMinute#
/** 
 * Returns the minute of a DateTime value
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@...]
 *  expect: 34
 * given: [1925-01-14 06:47:01.003+11:00@...]
 *  expect: 47
 *
 * @param dateTime The given DateTime
 * @return The minute of the given DateTime
 */
int GetMinute(DateTime dateTime);
GetSecond#
/** 
 * Returns the second of a DateTime value
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@...]
 *  expect: 15
 * given: [1925-01-14 06:47:01.003+11:00@...]
 *  expect: 1
 *
 * @param dateTime The given DateTime
 * @return The second of the given DateTime
 */
int GetSecond(DateTime dateTime);
GetMillisecond#
/** 
 * Returns the millisecond of a DateTime value
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@...]
 *  expect: 532
 * given: [1925-01-14 06:47:01.003+11:00@...]
 *  expect: 3
 *
 * @param dateTime The given DateTime
 * @return The millisecond of the given DateTime
 */
int GetMillisecond(DateTime dateTime);
GetTimeZone#
/** 
 * Returns the time zone of a Date or DateTime value
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *  expect: America/New_York
 * given: [1925-01-14 06:47:01.003+11:00@Australia/Sydney]
 *  expect: Australia/Sydney
 *
 * @param date The given Date or DateTime
 * @return The time zone of the given Date or DateTime
 */
String GetTimeZone(Date date);
AddYears#
/** 
 * Adds a number of years to a Date or DateTime
 *
 * Examples:
 * given: [2025-05-13 ...], 5
 *  expect: [2030-05-13 ...]
 * given: [2025-02-02 ...], -2
 *  expect: [2023-02-02 ...]
 *
 * @param date A Date or DateTime
 * @param years The number of years to add
 * @return A Date or DateTime with the given years added
 */
T AddYears(T date, long years);
AddMonths#
/** 
 * Adds a number of months to a Date or DateTime
 *
 * Examples:
 * given: [2025-05-13 ...], 5
 *  expect: [2025-10-13 ...]
 * given: [2025-02-02 ...], -2
 *  expect: [2024-12-02 ...]
 *
 * @param date A Date or DateTime
 * @param months The number of months to add
 * @return A Date or DateTime with the given months added
 */
T AddMonths(T date, long months);
AddDays#
/** 
 * Adds a number of days to a Date or DateTime
 *
 * Examples:
 * given: [2025-05-13 ...], 5
 *  expect: [2025-05-18 ...]
 * given: [2025-02-02 ...], -2
 *  expect: [2025-01-31 ...]
 *
 * @param date A Date or DateTime
 * @param days The number of days to add
 * @return A Date or DateTime with the given days added
 */
T AddDays(T date, long days);
AddHours#
/** 
 * Adds a number of hours to a DateTime
 *
 * Examples:
 * given: [2025-05-13 15:30:24.612...], 5
 *  expect: [2025-05-13 20:30:24.612...]
 * given: [2025-02-02 21:01:59.129...], -2
 *  expect: [2025-02-02 19:01:59.129...]
 *
 * @param dateTime A DateTime
 * @param hours The number of hours to add
 * @return A DateTime with the given hours added
 */
DateTime AddHours(DateTime dateTime, long hours);
AddMinutes#
/** 
 * Adds a number of minutes to a DateTime
 *
 * Examples:
 * given: [2025-05-13 15:30:24.612...], 5
 *  expect: [2025-05-13 15:35:24.612...]
 * given: [2025-02-02 21:01:59.129...], -2
 *  expect: [2025-02-02 20:59:59.129...]
 *
 * @param dateTime A DateTime
 * @param minutes The number of minutes to add
 * @return A DateTime with the given minutes added
 */
DateTime AddMinutes(DateTime dateTime, long minutes);
AddSeconds#
/** 
 * Adds a number of seconds to a DateTime
 *
 * Examples:
 * given: [2025-05-13 15:30:24.612...], 5
 *  expect: [2025-05-13 15:30:29.612...]
 * given: [2025-02-02 21:01:59.129...], -2
 *  expect: [2025-02-02 21:01:57.129...]
 *
 * @param dateTime A DateTime
 * @param seconds The number of seconds to add
 * @return A DateTime with the given seconds added
 */
DateTime AddSeconds(DateTime dateTime, long seconds);
AddMilliseconds#
/** 
 * Adds a number of milliseconds to a DateTime
 *
 * Examples:
 * given: [2025-05-13 15:30:24.612...], 5
 *  expect: [2025-05-13 15:30:24.617...]
 * given: [2025-02-02 21:01:59.129...], -2
 *  expect: [2025-02-02 21:01:59.127...]
 *
 * @param dateTime A DateTime
 * @param milliseconds The number of milliseconds to add
 * @return A DateTime with the given milliseconds added
 */
DateTime AddMilliseconds(DateTime dateTime, long milliseconds);
WithTimeZone#
/** 
 * Returns a new Date or DateTime that represents the
 * same local time or date in the new time zone as
 * the given date
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York],
 *        "Australia/Sydney"
 *  expect: [2025-05-13 22:34:15.532+11:00@Australia/Sydney]
 * given: [1925-01-14 06:47:01.003+11:00@Australia/Sydney],
 *        "America/New_York"
 *  expect: [1925-01-14 06:47:01.003-05:00@America/New_York]
 *
 * @param date A Date or DateTime
 * @return A new Date or DateTime with just the time zone
 *         component adjusted
 */
T WithTimeZone(T date);
InTimeZone#
/** 
 * Returns a new Date or DateTime that represents the
 * same point in time in a given time zone
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York],
 *        "Australia/Sydney"
 *  expect: [2025-05-14 16:34:15.532+11:00@Australia/Sydney]
 * given: [1925-01-14 06:47:01.003+11:00@Australia/Sydney],
 *        "America/New_York"
 *  expect: [1925-01-13 14:47:01.003-05:00@America/New_York]
 *
 * @param date A Date or DateTime
 * @return A new Date or DateTime in the new time zone
 */
T InTimeZone(T date);
ToDate#
/** 
 * Returns the Date component of a DateTime
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *  expect: [2025-05-13 00:00:00.000-05:00@America/New_York]
 * given: [1925-01-14 06:47:01.003+11:00@Australia/Sydney]
 *  expect: [1925-01-14 00:00:00.000+11:00@Australia/Sydney]
 *
 * @param dateTime The DateTime to be truncated
 * @return A Date representing the Date component of the DateTime
 */
Date ToDate(DateTime dateTime);
YearsBetween#
/** 
 * Calculates the number of full years between two Dates
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2026-05-13 22:34:15.532-05:00@America/New_York]
 *  expect: 1
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2026-05-13 21:34:15.532-05:00@America/New_York]
 *  expect: 0
 *
 * @param first The first date
 * @param second The second date
 * @return The number of years between the first date and the second.
 *         May be negative if the second date is before the first.
 */
long YearsBetween(Date first, Date second);
MonthsBetween#
/** 
 * Calculates the number of full months between two Dates
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-06-13 22:34:15.532-05:00@America/New_York]
 *  expect: 1
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-06-13 21:34:15.532-05:00@America/New_York]
 *  expect: 0
 *
 * @param first The first date
 * @param second The second date
 * @return The number of months between the first date and the second.
 *         May be negative if the second date is before the first.
 */
long MonthsBetween(Date first, Date second);
DaysBetween#
/** 
 * Calculates the number of full days between two Dates
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-14 22:34:15.532-05:00@America/New_York]
 *  expect: 1
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-14 21:34:15.532-05:00@America/New_York]
 *  expect: 0
 *
 * @param first The first date
 * @param second The second date
 * @return The number of days between the first date and the second.
 *         May be negative if the second date is before the first.
 */
long DaysBetween(Date first, Date second);
HoursBetween#
/** 
 * Calculates the number of full hours between two Dates
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-13 23:34:15.532-05:00@America/New_York]
 *  expect: 1
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-13 23:33:15.532-05:00@America/New_York]
 *  expect: 0
 *
 * @param first The first date
 * @param second The second date
 * @return The number of hours between the first date and the second.
 *         May be negative if the second date is before the first.
 */
long HoursBetween(Date first, Date second);
MinutesBetween#
/** 
 * Calculates the number of full minutes between two Dates
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-13 22:35:15.532-05:00@America/New_York]
 *  expect: 1
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-13 22:35:12.532-05:00@America/New_York]
 *  expect: 0
 *
 * @param first The first date
 * @param second The second date
 * @return The number of minutes between the first date and the second.
 *         May be negative if the second date is before the first.
 */
long MinutesBetween(Date first, Date second);
SecondsBetween#
/** 
 * Calculates the number of full seconds between two Dates
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-13 22:34:16.532-05:00@America/New_York]
 *  expect: 1
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-13 22:34:16.122-05:00@America/New_York]
 *  expect: 0
 *
 * @param first The first date
 * @param second The second date
 * @return The number of seconds between the first date and the second.
 *         May be negative if the second date is before the first.
 */
long SecondsBetween(Date first, Date second);
MillisecondsBetween#
/** 
 * Calculates the number of full milliseconds between two Dates
 *
 * Examples:
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-13 22:34:15.533-05:00@America/New_York]
 *  expect: 1
 * given: [2025-05-13 22:34:15.532-05:00@America/New_York]
 *        [2025-05-13 23:34:16.532-05:00@America/New_York]
 *  expect: 1000
 *
 * @param first The first date
 * @param second The second date
 * @return The number of milliseconds between the first date and the second.
 *         May be negative if the second date is before the first.
 */
long MillisecondsBetween(Date first, Date second);
FormatDate#
/** 
 * Formats a Date or DateTime into a String
 *
 * Examples:
 * given: [2025-02-13 22:34:15.532-05:00@America/New_York],
 *        "d MMM yy HH:mm:ssxxx'@'VV"
 *  expect: 13 Feb 25 22:34:15-05:00@America/New_York
 * given: [2025-07-13 22:34:15.532-05:00@America/New_York],
 *        "d/M"
 *  expect: "13/7"
 *
 * @param date A Date or DateTime to format
 * @param pattern A pattern to format the Date or DateTime
 * @return A formatted version of the given Date or DateTime
 */
String FormatDate(Date date, String pattern);

Pattern Strings are explained in the JDK Documentation.

ParseDate#
/** 
 * Parses a Date from a String
 *
 * Examples:
 * given: "2025-02-17",
 *        "yyyy-MM-dd"
 *  expect: [2025-02-17 00:00:00.000+XX:XX@XXX]
 *          where XX:XX@XXX depends on your system's local time zone
 * given: "1/4/25",
 *        "d/M/yy",
 *        "Australia/Sydney"
 *  expect: [2025-04-01 00:00:00.000+11:00@Australia/Sydney]
 *
 * @param text A String representing a date
 * @param pattern A pattern describing the format of the String
 * @param timeZone An identifier for a time zone.
 *          e.g. "Australia/Sydney"
 *        OPTIONAL, default = Your local system time zone
 * @return The Date represented by the given String
 * @implSpec
 *   Precondition: The String needs to represent a valid date
 *                 in a valid format
 */
Date ParseDate(String text, String pattern, String timeZone);

Pattern Strings are explained in the JDK Documentation.

ParseDateTime#
/** 
 * Parses a DateTime from a String
 *
 * Examples:
 * given: "2025-02-17 09:00",
 *        "yyyy-MM-dd HH:mm"
 *  expect: [2025-02-17 09:00:00.000+XX:XX@XXX]
 *          where XX:XX@XXX depends on your system's local time zone
 * given: "1/4/25 14:45:13+11:00 in Australia/Sydney",
 *        "d/M/yy HH:mm:ssxxx 'in' VV"
 *  expect: [2025-04-01 14:15:13.000+11:00@Australia/Sydney]
 *
 * @param text A String representing a date and time
 * @param pattern A pattern describing the format of the String
 * @return The DateTime represented by the given String
 * @implSpec
 *   Precondition: The String needs to represent a valid date
 *                 and time in a valid format
 */
DateTime ParseDateTime(String text, String pattern);

Pattern Strings are explained in the JDK Documentation.

HigherOrder#

Functions#

Bind ; Map ; BuildList ; Sort ; Fold ; FoldLeft ; Map ; Map ; Filter

Bind#
/** 
 * Applies a function to a Maybe value if it is Something,
 * otherwise returns Nothing
 *
 * Examples:
 * given: Something(50), x -> Something(x+10)
 *  expect: Something(60)
 * given: Something(50), x -> Nothing()
 *  expect: Nothing()
 * given: Nothing(), x -> Something(x+10)
 *  expect: Nothing()
 *
 * @param maybe The Maybe-value to whose content we want to
 *          apply a function
 * @param fun The function we want to apply to the value in the Maybe
 */
<T, U> Maybe<U> Bind(Maybe<T> maybe, Function<T, Maybe<U>> fun);
Map#
/** 
 * Applies a function to a Maybe value if it is Something,
 * otherwise returns Nothing
 *
 * Examples:
 * given: Something(50), x -> x+10
 *  expect: Something(60)
 * given: Nothing(), x -> x+10
 *  expect: Nothing()
 *
 * @param maybe The Maybe-value to whose content we want to
 *          apply a function
 * @param fun The function we want to apply to the value in the Maybe
 */
<T, U> Maybe<U> Map(Maybe<T> maybe, Function<T, U> fun);
BuildList#
/** 
 * Creates a list of a given length based on a generator function
 *
 * Examples:
 * given: 0, x->x
 *  expect: []
 * given: 4, x->x*2
 *  expect: [0, 2, 4, 6]
 *
 * @param length The length of the new list
 * @param generator A function that, given the index of an element
 *          in the list, produces the element
 * @return A new list with elements constructed using the generator
 */
<T> ConsList<T> BuildList(int length, Function<Integer, T> generator);
Sort#
/** 
 * Sorts a given list, using a given comparison function.
 *
 * Examples:
 * given: [], (x,y)->0
 *  expect: []
 * given: [4, 1, 3, 2], (x,y)->0
 *  expect: [4, 1, 3, 2]
 * given: [4, 1, 3, 2], (x,y) -> -Compare(x,y)
 *  expect: [4, 3, 2, 1]
 *
 * @param list The list to be sorted
 * @param comparator The function to use to compare any two elements
 *          of T. Its behavior should be like for the
 *          Compare function, i.e. return 0 if the elements
 *          are equal, a negative integer if the first
 *          element is "less" than the second, and a
 *          positive integer otherwise.
 * @return A version of the given list, sorted using the comparator
 */
<T> ConsList<T> Sort(ConsList<T> list, BiFunction<T, T, Integer> comparator);
Fold#
/** 
 * Combines the values of a list with a given aggregator
 * function, following a normal recursive template.
 *
 * Examples:
 * given: (x, y) -> x + y, 0, []
 *  expect: 0
 * given: (x, y) -> x + y, 0, [1, 2, 3]
 *  expect: 6
 * given: (x, y) -> x * y, 1, [1, 2, 3]
 *  expect: 6
 * given: (x, y) -> x + y, "", ["A", "B", "C"]
 *  expect: ABC
 *
 * @param aggregator The function used to combine the elements of
 *          the list. The first argument is an element of
 *          the list, the second argument is an intermediate
 *          result of having already combined some elements
 *          of the list.
 * @param start The starting value of the combination result
 * @param list The list whose elements should be combined
 * @return The result of combining the elements of the list
 */
<S, T> T Fold(BiFunction<S, T, T> aggregator, T start, ConsList<S> list);
FoldLeft#
/** 
 * Combines the values of a list with a given aggregator
 * function, combining values from the start of the list.
 *
 * Examples:
 * given: (x, y) -> x + y, 0, []
 *  expect: 0
 * given: (x, y) -> x + y, 0, [1, 2, 3]
 *  expect: 6
 * given: (x, y) -> x * y, 1, [1, 2, 3]
 *  expect: 6
 * given: (x, y) -> x + y, "", ["A", "B", "C"]
 *  expect: CBA
 *
 * @param aggregator The function used to combine the elements of
 *          the list. The first argument is an element of
 *          the list, the second argument is an intermediate
 *          result of having already combined some elements
 *          of the list.
 * @param start The starting value of the combination result
 * @param list The list whose elements should be combined
 * @return The result of combining the elements of the list
 */
<S, T> T FoldLeft(BiFunction<S, T, T> aggregator, T start, ConsList<S> list);
Map#
/** 
 * Applies a function to each element of a list, and produces
 * a list of the results of those function calls
 *
 * Examples:
 * given: x -> x + 1, []
 *  expect: []
 * given: x -> x + 1, [1, 2, 3]
 *  expect: [2, 3, 4]
 * given: x -> ToString(x), [1, 2]
 *  expect: ["1", "2"]
 *
 * @param mapper The function to convert values from S to T
 * @param list The list of arguments to the mapper
 * @return A list of the results of applying the mapper
 *         to each element of the given list.
 */
<S, T> ConsList<T> Map(Function<S, T> mapper, ConsList<S> list);
Map#
/** 
 * Applies a two-argument function to each pair of elements of two
 * equal-length lists, and produces a list of the results of those
 * function calls
 *
 * Examples:
 * given: (x, y) -> x + y, [], []
 *  expect: []
 * given: (x, y) -> x + y, [1, 2, 3], [4, 5, 6]
 *  expect: [5, 7, 9]
 * given: (x, y) -> ToString(x), [1, 2], [3, 4]
 *  expect: ["1", "2"]
 *
 * @param mapper The function apply to values of types S and T
 * @param list1 The first list of arguments
 * @param list2 The second list of arguments
 * @return A list of the results of applying the mapper
 *         to each pair of elements of the given lists.
 * @implSpec
 *   Precondition: list1 and list2 must be of equal length
 */
<S, T, U> ConsList<U> Map(BiFunction<S, T, U> mapper, ConsList<S> list1, ConsList<T> list2);
Filter#
/** 
 * Filters a list based on a given predicate
 *
 * Examples:
 * given: x -> x%2 == 0, [1,2,3,4,5]
 *  expect: [2,4]
 * given: x -> Length(x) > 0, [[], [1,2,3], [5]]
 *  expect: [[1,2,3], [5]]
 *
 * @param predicate The predicate that elements of the list need
 *          to satisfy to stay in the filtered list
 * @param list The list we want to filter
 * @return A list that contains only those elements of the given
 *         list where the predicate returns true.
 */
<T> ConsList<T> Filter(Predicate<T> predicate, ConsList<T> list);

Lambdas#

Functions#

Curry ; UnCurryFunction ; CurryPredicate ; UnCurryPredicate ; PairFunction ; UnpairFunction ; Compose ; ComposeAnd ; ComposeOr ; BiComposeAnd ; BiComposeOr

Curry#
/** 
 * Converts a two-argument BiFunction to its curried equivalent
 *
 * Examples:
 * given: (x, y) -> x + y
 *  expect: x -> y -> x + y (effectively)
 *
 * @param fun The function to be curried
 * @return The curried version of the given function
 */
<A1, A2, R> Function<A1, Function<A2, R>> Curry(BiFunction<A1, A2, R> fun);
UnCurryFunction#
/** 
 * Converts a curried two-argument function to a BiFunction
 *
 * Examples:
 * given: x -> y -> x + y
 *  expect: (x, y) -> x + y (effectively)
 *
 * @param fun The function to be uncurried
 * @return The uncurried version of the given function
 */
<A1, A2, R> BiFunction<A1, A2, R> UnCurryFunction(Function<A1, Function<A2, R>> fun);
CurryPredicate#
/** 
 * Converts a two-argument BiPredicate to its curried equivalent
 *
 * Examples:
 * given: (x, y) -> x + y == 5
 *  expect: x -> y -> x + y == 5 (effectively)
 *
 * @param fun The predicate to be curried
 * @return The curried version of the given predicate
 */
<A1, A2> Function<A1, Predicate<A2>> CurryPredicate(BiPredicate<A1, A2> fun);
UnCurryPredicate#
/** 
 * Converts a curried two-argument function to a BiPredicate
 *
 * Examples:
 * given: x -> y -> x + y == 5
 *  expect: (x, y) -> x + y == 5 (effectively)
 *
 * @param fun The predicate to be uncurried
 * @return The uncurried version of the given function/predicate
 */
<A1, A2> BiPredicateA1, A2> UnCurryPredicate(Function<A1, Predicate<A2>> fun);
PairFunction#
/** 
 * Converts a two-argument BiFunction to a function
 * that accepts a pair of arguments.
 *
 * Examples:
 * given: (x, y) -> x + y
 *  expect: x -> x.first() + x.second() (effectively)
 *
 * @param fun The function to convert to a single-argument function
 * @return The pair-curried version of the given function
 */
<A1, A2, R> Function<Pair<A1, A2>, R> PairFunction(BiFunction<A1, A2, R> fun);
UnpairFunction#
/** 
 * Converts a function on pairs to a BiFunction
 *
 * Examples:
 * given: x -> x.first() + y.second()
 *  expect: (x, y) -> x + y (effectively)
 *
 * @param fun The function to have its arguments expanded
 * @return The pair-uncurried version of the given function
 */
<A1, A2, R> BiFunction<A1, A2, R> UnpairFunction(Function<Pair<A1, A2>, R> fun);
Compose#
/** 
 * Composes to functions to a new function that first
 * applies the first function to its argument, and then
 * the second function to the output of the first call.
 *
 * Examples:
 * given: StringToInt, x -> x + 1
 *  expect: x -> StringToInt(x) + 1 (effectively)
 *
 * @param fun1 The first function to compose
 * @param fun2 The second function to compose
 * @return The composed function
 */
<T, U, R> Function<T, R> Compose(Function<T, U> fun1, Function<U, R> fun2);
ComposeAnd#
/** 
 * Composes two predicates to a new predicate that
 * holds if both composed predicates hold on its
 * argument
 *
 * Examples:
 * given: x -> x > 50, x -> x < 100
 *  expect: x -> x > 50 && x < 100 (effectively)
 *
 * @param pred1 The first predicate to compose
 * @param pred2 The second predicate to compose
 * @return The composed predicate
 */
<T> Predicate<T> ComposeAnd(Predicate<T> pred1, Predicate<T> pred2);
ComposeOr#
/** 
 * Composes two predicates to a new predicate that
 * holds if either of the composed predicates holds
 * on its argument
 *
 * Examples:
 * given: x -> x > 50, x -> x < -50
 *  expect: x -> x > 50 || x < -50 (effectively)
 *
 * @param pred1 The first predicate to compose
 * @param pred2 The second predicate to compose
 * @return The composed predicate
 */
<T> Predicate<T> ComposeOr(Predicate<T> pred1, Predicate<T> pred2);
BiComposeAnd#
/** 
 * Composes two predicates on different types to
 * a new BiPredicate that holds if both composed
 * predicates hold on their respective arguments
 *
 * Examples:
 * given: x -> x > 50, x -> Equals(x, "A")
 *  expect: (x, y) -> x > 50 && Equals(y, "A") (effectively)
 *
 * @param pred1 The first predicate to compose
 * @param pred2 The second predicate to compose
 * @return The composed predicate
 */
<T, U> BiPredicate<T, U> BiComposeAnd(Predicate<T> pred1, Predicate<U> pred2);
BiComposeOr#
/** 
 * Composes two predicates on different types to
 * a new BiPredicate that holds if either of the
 * composed predicates holds on their respective
 * argument
 *
 * Examples:
 * given: x -> x > 50, x -> Equals(x, "A")
 *  expect: (x, y) -> x > 50 || Equals(y, "A") (effectively)
 *
 * @param pred1 The first predicate to compose
 * @param pred2 The second predicate to compose
 * @return The composed predicate
 */
<T, U> BiPredicate<T, U> BiComposeOr(Predicate<T> pred1, Predicate<U> pred2);

Lists#

Provides support for lists. We’ll use the following notation in examples:

  • [] describes the empty list Nil<>()
  • x :: l describes a Cons<>(x, l)
  • [a, b, c] describes a list, represented by Cons<>(a, Cons<>(b, Cons<>(c, Nil<>())))

Itemizations#

ConsList

ConsList#
/**
 * Represents lists of values.
 * It is one of:
 * - The list is empty
 * - A non-empty list, consisting of at least one element,
 *    plus some other list
 */
sealed interface ConsList<T>permits Nil, Cons{}

// TEMPLATE:
// {
//     ...
//     return ... switch(conslist) {
//         case Nil<T>() ->  ... ;
//         case Cons<T>(var element, var rest) -> 
//              ... element ... [recursiveCall](... rest ...) ... ;
//     } ...;
// }

/**
 * Represents the empty list
 * Examples:
 * - Nil<Integer>()
 * - Nil<String>()
 */
record Nil<T>(
) implements ConsList<T>{}
/**
 * Represents a non-empty list consisting of at least one element
 * Examples:
 * - Cons<String>("Hello", Nil<String>())
 * - Cons<Integer>(1, Cons<Integer>(2, Nil<Integer>()))
 * @param element The first element of the list
 * @param rest The rest of the list, which may be empty
 */
record Cons<T>(
    T element,
    ConsList<T> rest) implements ConsList<T>{}

Functions#

MakeList ; BuildList ; BuildList ; IsEmpty ; First ; Rest ; Length ; Nth ; Append ; Sort ; Zip ; Unzip

MakeList#
/** 
 * Creates a new ConsList with the given elements
 *
 * Examples:
 * given: [no arguments]
 *  expect: []
 * given: 1, 2
 *  expect: [1,2]
 *
 * @param elements Arbitrarily many elements that form the new list
 * @return A ConsList that contains the given elements
 */
<T> ConsList<T> MakeList(T... elements);
BuildList#
/** 
 * Creates a new ConsList<Integer> of given length
 * with elements ranging from 0 up to (excluding) length
 *
 * Examples:
 * given: 0
 *  expect: []
 * given: 4
 *  expect: [0, 1, 2, 3]
 *
 * @param length The length of the new list
 * @return A new list of integers from 0 up to (excluding) lenght
 */
ConsList<Integer> BuildList(int length);
BuildList#
/** 
 * Creates a list of a given length of all the same value
 *
 * Examples:
 * given: 0, "A"
 *  expect: []
 * given: 4, true
 *  expect: [true, true, true, true]
 *
 * @param length The length of the new list
 * @param value  - will be used as every element in the list
 * @return A new list of length times value
 */
<T> ConsList<T> BuildList(int length, T value);
IsEmpty#
/** 
 * Returns whether or not a list is empty
 *
 * Examples:
 * given: []
 *  expect: true
 * given: [1, 2, 3]
 *  expect: false
 *
 * @param list A possibly empty list
 * @return true if the list is empty, false if not
 */
<T> boolean IsEmpty(ConsList<T> list);
First#
/** 
 * Returns the first element of a list
 *
 * Examples:
 * given: [1]
 *  expect: 1
 * given: ["B", "C", "A", "D"]
 *  expect: "B"
 *
 * @param list A list - must be non-empty
 * @return The first element of the given list
 */
<T> T First(ConsList<T> list);
Rest#
/** 
 * Returns the rest of a list, past the first element
 *
 * Examples:
 * given: [1]
 *  expect: []
 * given: ["B", "C", "A", "D"]
 *  expect: ["C", "A", "D"]
 *
 * @param list A list - must be non-empty
 * @return The rest of the given list, past the first element
 */
<T> ConsList<T> Rest(ConsList<T> list);
Length#
/** 
 * Returns the length of a given list
 *
 * Examples:
 * given: []
 *  expect: 0
 * given: [1, 2, 3]
 *  expect: 3
 *
 * @param list The list whose length should be computed
 * @return The length of the given list
 */
<T> int Length(ConsList<T> list);
Nth#
/** 
 * Returns the nth element of a given list
 *
 * Examples:
 * given: [1], 0
 *  expect: 1
 * given: [1,2,3,4], 3
 *  expect: 4
 *
 * @param list A list whose element we want to extract
 * @param index The 0-based index of an element in the list
 * @return The element at the given index in the given list
 * @implSpec
 *   Precondition: 0 <= index < Length(list)
 */
<T> T Nth(ConsList<T> list, int index);
Append#
/** 
 * Appends two lists
 *
 * Examples:
 * given: [], []
 *  expect: []
 * given: [1, 2, 4], [3, 6]
 *  expect: [1, 2, 4, 3, 6]
 *
 * @param list1 The first list
 * @param list2 The list to be appended to the first list
 * @return A new list that is the result of appending the given ones
 */
<T> ConsList<T> Append(ConsList<T> list1, ConsList<T> list2);
Sort#
/** 
 * Sorts a given list of a comparable type T.
 * Comparable Types are:
 *   - String
 *   - the number types (int, double, ...)
 *   - booleans
 *   - Date
 *   - DateTime
 *
 * Examples:
 * given: []
 *  expect: []
 * given: [4, 1, 3, 2]
 *  expect: [1, 2, 3, 4]
 *
 * @param list The list to be sorted
 * @return A version of the given list, sorted by the standard 
 *         ordering of its elements (as with the Compare function)
 */
<T> ConsList<T> Sort(ConsList<T> list);
Zip#
/** 
 * Given two lists of equal length, produces a list
 * of pairs of their elements
 *
 * Examples:
 * given: [1,2,3], [4,5,6]
 *  expect: [Pair(1,4), Pair(2,5), Pair(3,6)]
 * given: [9, 10], ["A", "B"]
 *  expect: [Pair(9, "A"), Pair(10, "B")]
 *
 * @param list1 The first list
 * @param list2 The second list
 * @return A list of pairs of elements at the same indices
 *         as in the original lists
 */
<S, T> ConsList<Pair<S, T>> Zip(ConsList<S> list1, ConsList<T> list2);
Unzip#
/** 
 * Given a list of Pairs, returns a pair of lists
 * containing the first and second elements of the
 * Pairs, respectively
 *
 * Examples:
 * given: [Pair(1,4), Pair(2,5), Pair(3,6)]
 *  expect: Pair([1,2,3], [4,5,6])
 * given: [Pair(9, "A"), Pair(10, "B")]
 *  expect: Pair([9, 10], ["A", "B"])
 *
 * @param list1 The list of pairs
 * @return A pair of lists of the first and second elements of the pairs
 */
<S, T> Pair<ConsList<S>, ConsList<T>> Unzip(ConsList<Pair<S, T>> list1);

Maps#

A map (a.k.a. dictionary) is a data structure that associates keys to values, and explicitly stores these associations as key-value pairs. In a map, any two pairs must have different keys. There might be different keys associated to the same value, though. The order of key-value pairs is undefined in a map, meaning that one should not assume any particular order. We will be working with two different implementations of maps: ConsList-based maps and Hash maps.

ConsList-based maps rely on ConsList<Pair<K,V>> to store the association of keys and values, with K being the type of the map keys, and V that of the map values. Besides, such maps are immutable, meaning that functions operating on them return new maps instead of modifying them in-place

Hash maps are of type Map<K,V>. They are implemented under the hood smartly using the so-called hash functions to perform fast key look-ups, thus the name Hash maps. Besides, Hash maps are stateful maps (a.k.a. mutable) meaning that the functions operating on them modify the input maps in-place, instead of returning whole new maps.

The functions below provide support to perform operations on both kind of maps. We’ll use the following notation in examples:

  • {} denotes either: (1) the ConsList-based empty map, represented by Nil<Pair<K,V>>(), or (2) the empty Hash map
  • {k1:v1, k2:v2} denotes either: (1) a ConsList-based map with two key-value pairs represented by either Cons<>(Pair<>(k1,v1), Cons<>(Pair<>(k2,v2), Nil<>())) or Cons<>(Pair<>(k2,v2), Cons<>(Pair<>(k1,v1), Nil<>())), or (2) a Hash map with two key-value pairs

Functions#

MakeConsMap ; MakeHashMap ; Put ; Put ; Remove ; Remove ; Get ; Get ; ContainsKey ; ContainsKey ; GetKeys ; GetKeys

MakeConsMap#
/** 
 * Creates a new ConsList-based map with the given key-value pairs.
 * If there is more than one key-value pair with the same key
 * in the given key-value pairs, the right-most one is the one that
 * prevails in the resulting map
 *
 * Examples:
 * given: [no arguments]
 *  expect: {}
 * given: Pair<>("COMP1110",91), Pair<>("COMP6710",139)
 *  expect: {"COMP1110": 91, "COMP6710": 139}
 * given: Pair<>("COMP1110",91), Pair<>("COMP1110",89)
 *  expect: {"COMP1110": 89}
 *
 * @param pairs Arbitrarily many pairs that form the new
 *              ConstList-based map
 * @return A ConsList-based map that contains the given pairs
 */
<K,V> ConsList<Pair<K,V>> MakeConsMap(Pair<K,V>... pairs);
MakeHashMap#
/** 
 * Creates a new Hash map with the given key-value pairs.
 * If there is more than one key-value pair with the same key
 * in the given key-value pairs, the right-most one is the one that
 * prevails in the resulting map
 *
 * Examples:
 * given: [no arguments]
 *  expect: {}
 * given: Pair<>("COMP1110",91), Pair<>("COMP6710",139)
 *  expect: {"COMP1110": 91, "COMP6710": 139}
 * given: Pair<>("COMP1110",91), Pair<>("COMP1110",89)
 *  expect: {"COMP1110": 89}
 *
 * @param pairs Arbitrarily many pairs that form the new
 *              Hash map
 * @return A new Hash map that contains the given pairs
 */
<K,V> Map<K,V> MakeHashMap(Pair<K,V>... pairs);
Put#
/** 
 * Given a (1) ConsList-based map, (2) a key, and (3) a value,
 * returns a new ConsList-based map with a new key-value
 * pair (2)-(3) added to (1) if (2) is not present in (1)
 * or the value associated to (2) updated with (3) if (2)
 * is present in (1)
 *
 * Examples:
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1110", 89
 *  expect: {"COMP1110": 89, "COMP6710": 139}
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1730", 223
 *  expect: {"COMP1110": 89, "COMP6710": 139, "COMP1730": 223}
 *
 * @param map A ConstList-based map
 * @param key The key of the key-value pair
 * @param value The value of the key-value pair
 * @return A new ConsList-based map with a new key-value map added 
 *         to the input map if the given key is not present
 *         in the input map, or with the value associated to key
 *         updated with the given value if the key is present in
 *         the input map
 */
<K,V> ConsList<Pair<K,V>> Put(ConsList<Pair<K,V>> map, K key, V value);
Put#
/** 
 * Given a (1) Hash map, (2) a key, and (3) a value,
 * updates the stateful map (1) in-place with a new key-value
 * pair (2)-(3) added to (1) if (2) is not present in (1)
 * or the value associated to (2) updated with (3) if (2)
 * is present in (1)
 *
 * Examples:
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1110", 89
 *  expect: {"COMP1110": 89, "COMP6710": 139}
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1730", 223
 *  expect: {"COMP1110": 89, "COMP6710": 139, "COMP1730": 223}
 *
 * @param map A Hash map to be updated in-place
 * @param key The key of the key-value pair
 * @param value The value of the key-value pair
 * @return void
 */
<K,V> void Put(Map<K,V> map, K key, V value);
Remove#
/** 
 * Given (1) a ConsList-based map, and (2) a key,
 * returns a new ConsList-based map where the key-value
 * pair associated to (2) is removed from the input map.
 * If (2) is not present in (1), it just returns a copy
 * of the input map.
 *
 * Examples:
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1110"
 *  expect: {"COMP6710": 139}
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP6730"
 *  expect: {"COMP1110": 91, "COMP6710": 139}
 *
 * @param map A ConstList-based map
 * @param key The key of the key-value pair to be removed
 * @return A new ConsList-based map with a key-value pair
 *         removed from the input map if the given key is present
 *         in the input map, or a copy of the input map otherwise
 */
<K,V> ConsList<Pair<K,V>> Remove(ConsList<Pair<K,V>> map, K key);
Remove#
/** 
 * Given (1) a Hash map, and (2) a key,
 * updates the stateful map (1) in-place such that the key-value
 * pair associated to (2) is removed from (1).
 * If (2) is not present in (1), it leaves (1) untouched.
 *
 * Examples:
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1110"
 *  expect: {"COMP6710": 139}
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP6730"
 *  expect: {"COMP1110": 91, "COMP6710": 139}
 *
 * @param map A Hash map to be updated in-place
 * @param key The key of the key-value pair to be removed
 * @return void
 */
<K,V> void Remove(Map<K,V> map, K key);
Get#
/** 
 * Given (1) a ConsList-based map, and (2) a key,
 * returns the Something<V>(value) associated to (2)
 * if the key is present in (1) or Nothing<V>() otherwise
 *
 * Examples:
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1110"
 *  expect: Something<Integer>(91)
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP6730"
 *  expect: Nothing<Integer>()
 *
 * @param map A ConstList-based map
 * @param key The key whose associated value being looked-up
 * @return The value associated to the given key as
 *         Something<V>(value) if the key is present
 *         in the input map, and Nothing<V>() otherwise
 */
<K,V> Maybe<V> Get(ConsList<Pair<K,V>> map, K key);
Get#
/** 
 * Given (1) a Hash map, and (2) a key,
 * returns the Something<V>(value) associated to (2)
 * if the key is present in (1) or Nothing<V>() otherwise
 *
 * Examples:
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1110"
 *  expect: Something<Integer>(91)
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP6730"
 *  expect: Nothing<Integer>()
 *
 * @param map A Hash map
 * @param key The key whose associated value being looked-up
 * @return The value associated to the given key as
 *         Something<V>(value) if the key is present
 *         in the input map, and Nothing<V>() otherwise
 */
<K,V> Maybe<V> Get(Map<K,V> map, K key);
ContainsKey#
/** 
 * Given (1) a ConsList-based map, and (2) a key,
 * returns true if (2) is present in (1), and false otherwise
 *
 * Examples:
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1110"
 *  expect: true
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP6730"
 *  expect: false
 *
 * @param map A ConsList-based map
 * @param key The key being looked-up
 * @return true if the key is present in the input map,
 *         and false otherwise
 */
<K,V> boolean ContainsKey(ConsList<Pair<K,V>> map, K key);
ContainsKey#
/** 
 * Given (1) a Hash map, and (2) a key,
 * returns true if (2) is present in (1), and false otherwise
 *
 * Examples:
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP1110"
 *  expect: true
 * given: {"COMP1110": 91, "COMP6710": 139}, "COMP6730"
 *  expect: false
 *
 * @param map A Hash map
 * @param key The key being looked-up
 * @return true if the key is present in the input map,
 *         and false otherwise
 */
<K,V> boolean ContainsKey(Map<K,V> map, K key);
GetKeys#
/** 
 * Given a ConsList-based map, returns a list with the keys
 * present in the map
 *
 * Examples:
 * given: {}
 *  expect: []
 * given: {"COMP1110": 91, "COMP6710": 139}
 *  expect: ["COMP1110","COMP6710"]
 *
 * @param map A ConsList-based map
 * @return A list with the keys present in the input map
 */
<K,V> ConsList<K> GetKeys(ConsList<Pair<K,V>> map);
GetKeys#
/** 
 * Given a Hash map, returns a list with the keys
 * present in the map
 *
 * Examples:
 * given: {}
 *  expect: []
 * given: {"COMP1110": 91, "COMP6710": 139}
 *  expect: ["COMP1110","COMP6710"]
 *
 * @param map A Hash map
 * @return A list with the keys present in the input map
 */
<K,V> ConsList<K> GetKeys(Map<K,V> map);

Math#

Constants#

PI ; E

PI#
/**
 * Represents the mathematical constant pi
 */
double PI;
E#
/**
 * Represents the mathematical constant e
 */
double E;

Functions#

Abs ; Exp ; Pow ; Sqrt ; Round ; RoundInt ; Ceil ; CeilInt ; Floor ; FloorInt ; Log ; Log10 ; Sin ; Cos ; Tan ; ASin ; ACos ; ATan

Abs#
/** 
 * Converts a numeric value to its absolute value
 *
 * Examples:
 * given: 15
 *  expect: 15
 * given: -5.2
 *  expect: 5.2
 *
 * @param value An int, long, double, or float
 * @return The absolute value of the given numeric value,
 *         in the same type
 */
T Abs(T value);
Exp#
/** 
 * Returns Euler's number E raised to the given value
 *
 * Examples:
 * given: 0.0
 *  expect: 1.0
 * given: 2.0
 *  expect: 7.38905...
 *
 * @param value The power to which to raise E
 * @return E raised to value
 */
double Exp(double value);
Pow#
/** 
 * Raises the first argument to the power of the second argument
 *
 * Examples:
 * given: 4.0, 2.0
 *  expect: 16.0
 * given: 7.0, 0.0
 *  expect: 1.0
 *
 * @param base The base of the exponentiation
 * @param exponent The exponent
 * @return The base to the power of the exponent
 */
double Pow(double base, double exponent);
Sqrt#
/** 
 * Calculates the square root of a given value
 *
 * Examples:
 * given: 4.0
 *  expect: 2.0
 * given: 1.0
 *  expect: 1.0
 *
 * @param value A value >=0 of which to calculate the square root
 * @return The square root of value
 */
double Sqrt(double value);
Round#
/** 
 * Rounds a given floating point number to a long
 *
 * Examples:
 * given: 4.5
 *  expect: 5l
 * given: 7.1
 *  expect: 7l
 *
 * @param number The value to be rounded
 * @return A long, rounded with ties going to positive infinity
 */
long Round(double number);
RoundInt#
/** 
 * As Round above, but returns an int
 *
 * Examples:
 * given: 4.5
 *  expect: 5
 * given: 7.1
 *  expect: 7
 *
 * @param number The value to be rounded
 * @return An integer, rounded with ties going to positive infinity
 */
int RoundInt(double number);
Ceil#
/** 
 * Rounds a given floating point number up to a long
 *
 * Examples:
 * given: 4.5
 *  expect: 5l
 * given: 7.1
 *  expect: 8l
 *
 * @param number The value to be rounded up
 * @return A long, rounded up towards positive infinity
 */
long Ceil(double number);
CeilInt#
/** 
 * As Ceil above, but returns an int
 *
 * Examples:
 * given: 4.5
 *  expect: 5
 * given: 7.1
 *  expect: 8
 *
 * @param number The value to be rounded up
 * @return An integer, rounded up towards positive infinity
 */
int CeilInt(double number);
Floor#
/** 
 * Rounds a given floating point number down to a long
 *
 * Examples:
 * given: 4.5
 *  expect: 4l
 * given: 7.1
 *  expect: 7l
 *
 * @param number The value to be rounded down
 * @return A long, rounded down towards negative infinity
 */
long Floor(double number);
FloorInt#
/** 
 * As Floor above, but returns an int
 *
 * Examples:
 * given: 4.5
 *  expect: 4
 * given: 7.1
 *  expect: 7
 *
 * @param number The value to be rounded down
 * @return An integer, rounded down towards negative infinity
 */
int FloorInt(double number);
Log#
/** 
 * Computes the natural logarithm of a given number
 *
 * Examples:
 * given: E
 *  expect: 1.0
 * given: E*E
 *  expect: 2.0
 *
 * @param number The number whose natural logarithm we want to compute
 * @return The natural logarithm of the given number
 */
double Log(double number);
Log10#
/** 
 * Computes the logarithm (base 10) of a given number
 *
 * Examples:
 * given: 10.0
 *  expect: 1.0
 * given: 100.0
 *  expect: 2.0
 *
 * @param number The number whose logarithm (base 10) we want to compute
 * @return The logarithm (base 10) of the given number
 */
double Log10(double number);
Sin#
/** 
 * Computes the trigonometric sine of an angle
 *
 * Examples:
 * given: PI
 *  expect: 0.0
 * given: PI/2.0
 *  expect: 1.0
 *
 * @param angle The angle in radians (i.e. PI = 180 degrees)
 * @return The sine of the given angle
 */
double Sin(double angle);
Cos#
/** 
 * Computes the trigonometric cosine of an angle
 *
 * Examples:
 * given: PI
 *  expect: -1.0
 * given: PI/2.0
 *  expect: 0.0
 *
 * @param angle The angle in radians (i.e. PI = 180 degrees)
 * @return The cosine of the given angle
 */
double Cos(double angle);
Tan#
/** 
 * Computes the trigonometric tangent of an angle
 *
 * Examples:
 * given: PI
 *  expect: 0.0
 * given: PI/4.0
 *  expect: 1.0
 *
 * @param angle The angle in radians (i.e. PI = 180 degrees)
 * @return The tangent of the given angle
 */
double Tan(double angle);
ASin#
/** 
 * Computes the trigonometric arc sine of an angle
 *
 * Examples:
 * given: 0.0
 *  expect: PI
 * given: 1.0
 *  expect: PI/2.0
 *
 * @param angle The angle in radians (i.e. PI = 180 degrees)
 * @return The arc sine of the given angle
 *         Value is between -PI/2 and PI/2
 */
double ASin(double angle);
ACos#
/** 
 * Computes the trigonometric arc cosine of an angle
 *
 * Examples:
 * given: -1.0
 *  expect: PI
 * given: 0.0
 *  expect: PI/2.0
 *
 * @param angle The angle in radians (i.e. PI = 180 degrees)
 * @return The arc cosine of the given angle
 *         Value is between 0.0 and PI
 */
double ACos(double angle);
ATan#
/** 
 * Computes the trigonometric arc tangent of an angle
 *
 * Examples:
 * given: 0.0
 *  expect: PI
 * given: 1.0
 *  expect: PI/4.0
 *
 * @param angle The angle in radians (i.e. PI = 180 degrees)
 * @return The arc tangent of the given angle
 *         Value is between -PI/2 and PI/2
 */
double ATan(double angle);

Strings#

Functions#

Format ; Concatenate ; SubString ; Contains ; StartsWith ; EndsWith ; Replace ; Length ; IndexOf ; LastIndexOf ; Trim ; UpperCase ; LowerCase ; GetCharAt

Format#
/** 
 * A wrapper for Java's and therefore C's format capabilities.
 * Advanced users only!
 *
 * Examples:
 * given: "$ %(,.2f", 6217.58
 *  expect: "$ (6,217.58)"
 * given: "Hello, %s!", "John"
 *  expect: "Hello, John!"
 *
 * @param format A format string (see explanation below)
 * @param args Arbitrarily many more arguments to be formatted into the string
 * @return A formatted String
 */
String Format(String format, Object... args);

This is a Wrapper for Java’s String formatting functionality. You don’t technically need it, and it is here as a convenience feature for some advanced users. You’ll need to consult the documentation of format strings.

Concatenate#
/** 
 * Concatenates a number of Strings
 *
 * Examples:
 * given: "a", "b", "c"
 *  expect: "abc"
 * given: "Hello, ", "World!"
 *  expect: "Hello, World!"
 *
 * @param strings The strings to concatenate
 * @return The String resulting from concatenating the arguments
 */
String Concatenate(String... strings);
SubString#
/** 
 * Returns a part of a given String
 *
 * Examples:
 * given: "Hello", 3
 *  expect: "lo"
 * given: "Hello", 1, 4
 *  expect: "ell"
 *
 * @param string The string whose part we want to extract
 * @param startIndex The index (>=0, <Length(String)) of the first
 *          character to include in the output.
 * @param endIndex The index (>=0, <=Length(String)) of the first 
 *          character to *not* be included in the output.
 *        OPTIONAL, default = Length(string)
 * @return The part of the String between the given indices.
 */
String SubString(String string, int startIndex, int endIndex);
Contains#
/** 
 * Checks whether a String contains another String
 *
 * Examples:
 * given: "Hello,", "He"
 *  expect: true
 * given: "Hello", "W"
 *  expect: false
 *
 * @param haystack The larger String, in which we are searching
 * @param needle The String we are searching for
 * @return true if haystack contains needle, false if not
 */
boolean Contains(String haystack, String needle);
StartsWith#
/** 
 * Checks whether a String starts with another String
 *
 * Examples:
 * given: "Hello", "Hell"
 *  expect: true
 * given: "Hello", "ello"
 *  expect: false
 *
 * @param string The larger String whose start we are looking at
 * @param prefix The prefix we are looking for
 * @return True if string starts with prefix, false if not
 */
boolean StartsWith(String string, String prefix);
EndsWith#
/** 
 * Checks whether a String ends with another String
 *
 * Examples:
 * given: "Hello", "Hell"
 *  expect: false
 * given: "Hello", "ello"
 *  expect: true
 *
 * @param string The larger String whose end we are looking at
 * @param postfix The postfix we are looking for
 * @return True if string ends with postfix, false if not
 */
boolean EndsWith(String string, String postfix);
Replace#
/** 
 * Replaces a String with another String in a given String
 *
 * Examples:
 * given: "Hello", "Hi", "Hello World!"
 *  expect: "Hi World!"
 * given: "ell", "", "Hello, hello, hello!"
 *  expect: "Ho, ho, ho!"
 * given: "x", "y", "Hello"
 *  expect: "Hello"
 *
 * @param replace The String to be replaced
 * @param withString The String to replace "replace" with
 * @param inString The overall String in which "withString" should
 *          replace "replace"
 * @return "inString" with all occurences of "replace"
 *         replaced with "withString"
 */
String Replace(String replace, String withString, String inString);
Length#
/** 
 * Returns the length of a String
 *
 * Examples:
 * given: ""
 *  expect: 0
 * given: "Hello"
 *  expect: 5
 *
 * @param string The String whose length we want to determine
 * @return The length of the String
 */
int Length(String string);
IndexOf#
/** 
 * Returns the start index of a String in a given String
 *
 * Examples:
 * given: "o", "Hello"
 *  expect: 4
 * given: "x", "Hello"
 *  expect: -1
 * given: "ell", "Well well well", 4
 *  expect: 6
 *
 * @param find The String to find
 * @param inString The String in which to find the other String
 * @param fromIndex An index before which occurrences of find
 *          should be ignored
 *        OPTIONAL, default = 0
 * @return The index (>=0) of the first occurence of find in inString
 *         after fromIndex, or -1 if it does not occur.
 */
int IndexOf(String find, String inString, int fromIndex);
LastIndexOf#
/** 
 * Returns the last start index of a String in a given String
 *
 * Examples:
 * given: "oo", "Hellooo"
 *  expect: 5
 * given: "x", "Hellooo"
 *  expect: -1
 * given: "ell", "Well well well", 10
 *  expect: 6
 *
 * @param find The String to find
 * @param inString The String in which to find the other String
 * @param fromIndex An index after which occurrences of find
 *          should be ignored
 *        OPTIONAL, default = Length(inString)
 * @return The index (>=0) of the last occurence of find in inString
 *         before fromIndex, or -1 if it does not occur.
 */
int LastIndexOf(String find, String inString, int fromIndex);
Trim#
/** 
 * Removes whitespace from the ends of a String
 *
 * Examples:
 * given: "   a   "
 *  expect: "a"
 * given: "Hello "
 *  expect: "Hello"
 *
 * @param string The String that should be trimmed
 * @return A version of the given String without
 *         preceding or trailing whitespace
 */
String Trim(String string);
UpperCase#
/** 
 * Converts all applicable characters of a String to upper case
 *
 * Examples:
 * given: "Hello"
 *  expect: "HELLO"
 * given: "3445"
 *  expect: "3445"
 *
 * @param string The String that should be converted to upper case
 * @return A version of the given String with all upper case letters
 */
String UpperCase(String string);
LowerCase#
/** 
 * Converts all applicable characters of a String to lower case
 *
 * Examples:
 * given: "Hello"
 *  expect: "hello"
 * given: "3445"
 *  expect: "3445"
 *
 * @param string The String that should be converted to lower case
 * @return A version of the given String with all lower case letters
 */
String LowerCase(String string);
GetCharAt#
/** 
 * Returns the character at a given index in a String
 *
 * Examples:
 * given: "Hello", 2
 *  expect: 'l'
 * given: "World", 0
 *  expect: 'W'
 *
 * @param string The String in which to look for a character
 * @param index The index (>=0, < Length(string)) of the character
 * @return The character at the given index of the given String
 */
char GetCharAt(String string, int index);
bars search caret-down plus minus arrow-right times