this_employee = ("Folland, Mary", 10560, False, 35)
The list instead is the most commonly used data structure in Miranda. It is written delimited by square brackets and with comma-separated elements, all of which must be of the same type: week_days = ["Mon","Tue","Wed","Thur","Fri"]
List concatenation is ++, subtraction is --, construction is :, sizing is # and indexing is !, so: days = week_days ++ ["Sat","Sun"] days = "Nil":days days!0 → "Nil" days = days -- ["Nil"] #days → 7
There are several list-building shortcuts: .. is used for lists whose elements form an arithmetic series, with the possibility for specifying an increment other than 1: fac n = product [1..n] odd_sum = sum [1,3..100]
More general and powerful list-building facilities are provided by "list comprehensions" (previously known as "ZF expressions"), which come in two main forms: an expression applied to a series of terms, e.g.: squares = [ n * n | n <- [1..] ]
(which is read: list of n squared where n is taken from the list of all positive integers) and a series where each term is a function of the previous one, e.g.: powers_of_2 = [ n | n <- 1, 2*n .. ]
As these two examples imply, Miranda allows for lists with an infinite number of elements, of which the simplest is the list of all positive integers: [1..] The notation for function application is simply juxtaposition, as in sin x. In Miranda, as in most other purely functional languages, functions are first-class citizens, which is to say that they can be passed as parameters to other functions, returned as results, or included as elements of data structures. What is more, a function requiring two or more parameters may be "partially parameterised", or curried, by supplying less than the full number of parameters. This gives another function which, given the remaining parameters, will return a result. For example: add a b = a + b
increment = add 1
is a roundabout way of creating a function "increment" which adds one to its argument. In reality, add 4 7 takes the two-parameter function add, applies it to 4 obtaining a single-parameter function that adds four to its argument, then applies that to 7. Any function taking two parameters can be turned into an infix operator (for example, given the definition of the add function above, the term $add is in every way equivalent to the + operator) and every infix operator taking two parameters can be turned into a corresponding function. Thus: increment = (+) 1
is the briefest way to create a function that adds one to its argument. Similarly, in half = (/ 2) reciprocal = (1 /)
two single-parameter functions are generated. The interpreter understands in each case which of the divide operator's two parameters is being supplied, giving functions which respectively divide a number by two and return its reciprocal. Although Miranda is a strongly typed programming language, it does not insist on explicit type declarations. If a function's type is not explicitly declared, the interpreter infers it from the type of its parameters and how they are used within the function. In addition to the basic types (char, num, bool), it includes an "anything" type where the type of a parameter does not matter, as in the list-reversing function: rev [] = [] rev (a:x) = rev x ++ [a]
which can be applied to a list of any data type, for which the explicit function type declaration would be: rev :: [*] -> [*]
Finally, it has mechanisms for creating and managing program modules whose internal functions are invisible to programs calling those modules.
[edit] Sample code The following Miranda script determines the set of all subsets of a set of numbers subsets [] = [[]] subsets (x:xs) = [[x] ++ y | y <- ys] ++ ys where ys = subsets xs
and this is a literate script for a function primes which gives the list of all prime numbers > || The infinite list of all prime numbers, by the sieve of Eratosthenes. The list of potential prime numbers starts as all integers from 2 onwards; as each prime is returned, all the following numbers that can exactly be divided by it are filtered out of the list of candidates. > primes = sieve [2..] > sieve (p:x) = p : sieve [n | n <- x; n mod p ~= 0]