prelude

General-purpose functions for lists, MAYBE and EITHER values, pairs and dictionaries. Import it with IMPORT prelude; it is not loaded automatically.

In the tables, a, b, c, k, v and r stand for any type, as in GIVEN a IS A TYPE. The inputs are listed in the order the function takes them.

Example:

-- Prelude Example: Demonstrating core list and Maybe patterns
-- Everything below is core syntax and built-ins, so this file needs no IMPORT.
-- The prelude itself is NOT automatic: reach for one of its functions and you
-- must write `IMPORT prelude` first, exactly as for any other library.

-- List construction using FOLLOWED BY (cons) and EMPTY
DECIDE `first few numbers` IS 1 FOLLOWED BY 2 FOLLOWED BY 3 FOLLOWED BY EMPTY
#EVAL `first few numbers`  -- LIST 1, 2, 3

-- Alternative: LIST syntax
DECIDE `more numbers` IS LIST 4, 5, 6
#EVAL `more numbers`  -- LIST 4, 5, 6

-- Pattern matching on lists with CONSIDER
GIVEN list IS A LIST OF NUMBER
GIVETH A NUMBER
`length of list` list MEANS
  CONSIDER list
  WHEN EMPTY THEN 0
  WHEN x FOLLOWED BY xs THEN 1 PLUS `length of list` xs

#EVAL `length of list` `first few numbers`  -- 3

-- Map: Apply function to each element
GIVEN list IS A LIST OF NUMBER
GIVETH A LIST OF NUMBER
`double all values` list MEANS
  CONSIDER list
  WHEN EMPTY THEN EMPTY
  WHEN x FOLLOWED BY xs THEN (x TIMES 2) FOLLOWED BY `double all values` xs

#EVAL `double all values` `first few numbers`  -- LIST 2, 4, 6

-- Filter: Keep elements matching predicate
GIVEN list IS A LIST OF NUMBER
GIVETH A LIST OF NUMBER
`keep only even numbers` list MEANS
  CONSIDER list
  WHEN EMPTY THEN EMPTY
  WHEN x FOLLOWED BY xs THEN
    IF x MODULO 2 EQUALS 0
    THEN x FOLLOWED BY `keep only even numbers` xs
    ELSE `keep only even numbers` xs

#EVAL `keep only even numbers` (LIST 1, 2, 3, 4, 5, 6)  -- LIST 2, 4, 6

-- Fold: Reduce list to single value (sum)
GIVEN list IS A LIST OF NUMBER
GIVETH A NUMBER
`sum of all values` list MEANS
  CONSIDER list
  WHEN EMPTY THEN 0
  WHEN x FOLLOWED BY xs THEN x PLUS `sum of all values` xs

#EVAL `sum of all values` `first few numbers`  -- 6

-- Maybe type: JUST for present values, NOTHING for absent
DECIDE `maybe has value` IS JUST 42
DECIDE `no value present` IS NOTHING

#EVAL `maybe has value`  -- JUST 42
#EVAL `no value present`     -- NOTHING

-- Pattern matching on Maybe
GIVEN maybe IS A MAYBE NUMBER
GIVETH A NUMBER
`get value or default to zero` maybe MEANS
  CONSIDER maybe
  WHEN NOTHING THEN 0
  WHEN JUST x THEN x

#EVAL `get value or default to zero` `maybe has value`  -- 42
#EVAL `get value or default to zero` `no value present`     -- 0

-- Either type: LEFT or RIGHT
DECIDE `successful result` IS RIGHT 100
DECIDE `error result` IS LEFT "error"

#EVAL `successful result`  -- RIGHT 100
#EVAL `error result`  -- LEFT "error"

-- Element membership check
GIVEN x IS A NUMBER
      list IS A LIST OF NUMBER
GIVETH A BOOLEAN
`is element in list` x list MEANS
  CONSIDER list
  WHEN EMPTY THEN FALSE
  WHEN y FOLLOWED BY ys THEN
    IF x EQUALS y THEN TRUE ELSE `is element in list` x ys

#EVAL `is element in list` 2 `first few numbers`  -- TRUE
#EVAL `is element in list` 9 `first few numbers`  -- FALSE

Lists

Building and reshaping

Function Inputs Gives What it does
append list1, list2: LIST OF a LIST OF a list1 followed by list2
concat lists: LIST OF LIST OF a LIST OF a All the lists joined into one
reverse list: LIST OF a LIST OF a The list in reverse order
replicate n: NUMBER, x: a LIST OF a n copies of x
range low, high: NUMBER LIST OF NUMBER The whole numbers from low to high, both included
map f: FUNCTION FROM a TO b, list: LIST OF a LIST OF b f applied to each item
filter f: FUNCTION FROM a TO BOOLEAN, list: LIST OF a LIST OF a The items for which f holds
take n: NUMBER, list: LIST OF a LIST OF a The first n items
drop n: NUMBER, list: LIST OF a LIST OF a The list without its first n items
takeWhile f: FUNCTION FROM a TO BOOLEAN, list: LIST OF a LIST OF a The leading items for which f holds
dropWhile f: FUNCTION FROM a TO BOOLEAN, list: LIST OF a LIST OF a The list from the first item for which f does not hold
zip list1: LIST OF a, list2: LIST OF b LIST OF PAIR OF a, b The two lists paired item by item
zipWith op: FUNCTION FROM a AND b TO c, list1: LIST OF a, list2: LIST OF b LIST OF c The two lists combined item by item with op
partition f: FUNCTION FROM a TO BOOLEAN, list: LIST OF a PAIR OF LIST OF a, LIST OF a The items for which f holds, and the rest
sort list: LIST OF NUMBER LIST OF NUMBER Sorted, smallest first
sortBy cmp: FUNCTION FROM a AND a TO BOOLEAN, list: LIST OF a LIST OF a Sorted so that cmp x y holds when x comes before y
insertBy cmp: FUNCTION FROM a AND a TO BOOLEAN, x: a, list: LIST OF a LIST OF a x inserted into a list already sorted by cmp
nub list: LIST OF a LIST OF a The list with duplicates removed
nubBy op: FUNCTION FROM a AND a TO BOOLEAN, list: LIST OF a LIST OF a Duplicates, as judged by op, removed
delete x: a, list: LIST OF a LIST OF a The list without the first item equal to x
deleteBy op: FUNCTION FROM a AND a TO BOOLEAN, x: a, list: LIST OF a LIST OF a The list without the first item that matches x by op

Questions about a list

Function Inputs Gives What it does
null list: LIST OF a BOOLEAN TRUE if the list is empty
count list: LIST OF a NUMBER The number of items
at list: LIST OF a, i: NUMBER a The item at position i, counting from 0
elem x: a, list: LIST OF a BOOLEAN TRUE if x is one of the items
all f: FUNCTION FROM a TO BOOLEAN, list: LIST OF a BOOLEAN TRUE if f holds for every item (TRUE for an empty list)
any f: FUNCTION FROM a TO BOOLEAN, list: LIST OF a BOOLEAN TRUE if f holds for at least one item
and list: LIST OF BOOLEAN BOOLEAN TRUE if every item is TRUE
or list: LIST OF BOOLEAN BOOLEAN TRUE if at least one item is TRUE
lookup key: a, list: LIST OF PAIR OF a, b MAYBE b The value paired with the first matching key, or NOTHING

at stops with an error past the end of the list.

Folds

Function Inputs Gives What it does
foldr cons: FUNCTION FROM a AND r TO r, nil: r, list: LIST OF a r Combines the items from the right, starting from nil
foldl op: FUNCTION FROM r AND a TO r, ini: r, list: LIST OF a r Combines the items from the left, starting from ini

Numbers

Function Inputs Gives What it does
sum list: LIST OF NUMBER NUMBER The total (0 for an empty list)
product list: LIST OF NUMBER NUMBER The product (1 for an empty list)
max x, y: NUMBER NUMBER The greater of the two
min x, y: NUMBER NUMBER The lesser of the two
maximum list: LIST OF NUMBER NUMBER The largest item; an error for an empty list
minimum list: LIST OF NUMBER NUMBER The smallest item; an error for an empty list
maximum1 x: NUMBER, list: LIST OF NUMBER NUMBER The largest of x and the items
minimum1 x: NUMBER, list: LIST OF NUMBER NUMBER The smallest of x and the items
even x: NUMBER BOOLEAN TRUE if x is even
odd x: NUMBER BOOLEAN TRUE if x is odd

max, min, maximum, minimum, maximum1 and minimum1 also accept MAYBE NUMBER values. NOTHING counts as absent: the other value wins, and only when every value is NOTHING, or the list is empty, is the result NOTHING.

With the prelude imported, <, <=, > and >= (and LESS THAN, AT MOST, GREATER THAN, AT LEAST) also compare two MAYBE NUMBER values. The comparison is FALSE when either side is NOTHING.

MAYBE values

Function Inputs Gives What it does
fromMaybe default: a, x: MAYBE a a The value inside x, or default if x is NOTHING
maybe just: FUNCTION FROM a TO b, nothing: b, x: MAYBE a b just applied to the value inside x, or nothing
orElse x, y: MAYBE a MAYBE a x if it holds a value, otherwise y
isJust x: MAYBE a BOOLEAN TRUE if x holds a value
isNothing x: MAYBE a BOOLEAN TRUE if x is NOTHING
asum list: LIST OF MAYBE a MAYBE a The first item that holds a value; firstJust is the same
catMaybes list: LIST OF MAYBE a LIST OF a The values of the items that hold one
mapMaybe f: FUNCTION FROM a TO MAYBE b, list: LIST OF a LIST OF b f applied to each item, keeping the results that hold a value
maybeToList x: MAYBE a LIST OF a An empty list or a list of one
listToMaybe list: LIST OF a MAYBE a The first item, or NOTHING for an empty list

EITHER values

Function Inputs Gives What it does
either left: FUNCTION FROM a TO c, right: FUNCTION FROM b TO c, x: EITHER a b c left applied to a LEFT value, right to a RIGHT value

Pairs

The prelude declares PAIR OF a, b with the fields fst and snd. Build one with PAIR OF x, y and read it with p's fst and p's snd.

Function Inputs Gives What it does
pmap f: FUNCTION FROM b TO c, p: PAIR OF a, b PAIR OF a, c f applied to the second value; mapSnd is the same
fmap f: FUNCTION FROM b TO c, list: LIST OF PAIR OF a, b LIST OF PAIR OF a, c f applied to the second value of each pair; mapPairs is the same

Dictionaries

Dictionary k v maps keys of type k to values of type v. It is a record whose contents field is a list of PAIR OF k, v, with one pair for each key.

Building a dictionary

Function Inputs Gives What it does
emptyDict none Dictionary k v A dictionary with no entries
singleToDict k: a, v: b Dictionary a b One entry; singleton is the same
pairToDict pair: PAIR OF k, v Dictionary k v One entry from a pair
listToDict pairs: LIST OF PAIR OF k, v Dictionary k v One entry per pair, as given; fromList is the same
fromListGrouped pairs: LIST OF PAIR OF k, v Dictionary k (LIST OF v) The values of each key collected into a list

Reading a dictionary

Function Inputs Gives What it does
dictLookup key: k, dict: Dictionary k v MAYBE v The value for key, or NOTHING
dictFindWithDefault default: v, key: k, dict: Dictionary k v v The value for key, or default
dictMember key: k, dict: Dictionary k v BOOLEAN TRUE if key has an entry
dictNotMember key: k, dict: Dictionary k v BOOLEAN TRUE if key has no entry
dictKeys dict: Dictionary k v LIST OF k All keys
dictElems dict: Dictionary k v LIST OF v All values
dictToList dict: Dictionary k v LIST OF PAIR OF k, v All entries as pairs
dictSize dict: Dictionary k v NUMBER The number of entries
dictIsEmpty dict: Dictionary k v BOOLEAN TRUE if there are no entries

Changing a dictionary

Each of these gives a new dictionary; the original is unchanged.

Function Inputs What it does
dictInsert key: k, value: v, dict: Dictionary k v Adds the entry, replacing any value for key
dictInsertWith combiner: FUNCTION FROM v AND v TO v, key: k, value: v, dict: Dictionary k v Adds the entry; if key has a value, stores combiner value (new, then old)
dictDelete key: k, dict: Dictionary k v Removes the entry for key
dictAdjust f: FUNCTION FROM v TO v, key: k, dict: Dictionary k v Applies f to the value for key, if there is one
dictUpdate f: FUNCTION FROM v TO MAYBE v, key: k, dict: Dictionary k v Replaces the value for key with what f gives, or removes it when f gives NOTHING
dictUnion dict1, dict2: Dictionary k v Both dictionaries' entries; for a key in both, dict1's value wins
dictUnionWith combiner: FUNCTION FROM v AND v TO v, dict1, dict2: Dictionary k v Both dictionaries' entries; for a key in both, combiner joins the two values

All of these give a Dictionary k v.

Working over all entries

Function Inputs Gives What it does
mapDict f: FUNCTION FROM v TO w, dict: Dictionary k v Dictionary k w f applied to every value
dictMapWithKey f: FUNCTION FROM k AND v TO w, dict: Dictionary k v Dictionary k w f applied to every key and value
filterDict pred: FUNCTION FROM v TO BOOLEAN, dict: Dictionary k v Dictionary k v The entries whose value satisfies pred
dictFilterWithKey pred: FUNCTION FROM k AND v TO BOOLEAN, dict: Dictionary k v Dictionary k v The entries whose key and value satisfy pred
foldrDict f: FUNCTION FROM v AND r TO r, z: r, dict: Dictionary k v r Combines the values from the right
foldlDict f: FUNCTION FROM r AND v TO r, z: r, dict: Dictionary k v r Combines the values from the left
dictFoldrWithKey f: FUNCTION FROM k AND v AND r TO r, z: r, dict: Dictionary k v r Combines keys and values from the right
dictFoldlWithKey f: FUNCTION FROM r AND k AND v TO r, z: r, dict: Dictionary k v r Combines keys and values from the left

Grouped pairs

Function Inputs Gives What it does
groupPairs pairs: LIST OF PAIR OF k, v LIST OF PAIR OF k, LIST OF v Collects the values of each key into a list
insertValue key: k, value: v, dictPairs: LIST OF PAIR OF k, LIST OF v LIST OF PAIR OF k, LIST OF v Adds value to the list for key, creating it if needed

Other functions

Function Inputs Gives What it does
id x: a a x itself
const x: a, y: b a x, ignoring y
APPEND x, y: STRING STRING Written between its inputs, x APPEND y: the two strings joined, like CONCAT x, y
TBD none a A placeholder of any type for a value not yet decided; evaluating it is an error