Skip to content

The Miranda Standard Environment

We give here, in alphabetical order, a brief explanation of all the identifiers in the Miranda standard environment, each followed by its definition (except in a few cases where the definition cannot conveniently be given in Miranda). The lines marked with a \> in column one are formal program text, the other lines in the file are comment. Note that a number of the functions given here are defined internally (for speed) even though their definitions could have been given in Miranda - in these cases the Miranda definition is given as a comment. This is the standard environment of Miranda release two.

abs takes the absolute value of a number - e.g. abs (-3) is 3, abs 3.5 is 3.5

> abs :: num->num
> abs x = -x, if x<0
>       =  x, otherwise

and applied to a list of truthvalues, takes their logical conjunction.

> and :: [bool]->bool
> and = foldr (&) True

arctan is the trigonometric function, inverse tangent. It returns a result in the range -pi/2 to pi/2. See also sin\',cos`.

> arctan :: num->num ||defined internally

bool is the type comprising the two truthvalues.

        bool ::= False | True ||primitive to Miranda

char\' is the type comprising ascii characters (e.g. \'a\', \'\\n).

        char :: type ||primitive to Miranda

cjustify applied to a number and a string, centre justifies the string in a field of the specified width. See also ljustify, rjustify\',spaces`.

> cjustify :: num->[char]->[char]
> cjustify n s = spaces lmargin++s++spaces rmargin
>                where
>                margin = n - # s
>                lmargin = margin div 2
>                rmargin = margin - lmargin

code applied to a character returns the integer which is its ascii code. E.g.

        code 'a' = 97.

See also decode.

> code :: char->num  ||defined internally

concat applied to a list of lists, joins them all together into a single list with ++. E.g.

        concat [[1,2],[],[3,4]] = [1,2,3,4].

> concat :: [[*]]->[*]
> concat = foldr (++) []

const is a combinator for creating constant-valued functions. E.g. (const 3) is the function that always returns 3.

> const :: *->**->*
> const x y = x

converse is a combinator for inverting the order of arguments of a two-argument function.

> converse :: (*->**->***)->**->*->***
> converse f a b = f b a

cos is the trigonometric cosine function, argument in radians.

> cos :: num->num   ||defined internally

decode applied to a number between 0 and 255 returns the corresponding value of type char.

> decode :: num->char ||defined internally

digit is a predicate on characters. True if the character is a digit. See also letter.

> digit :: char->bool
> digit x = '0'<=x<='9'

drop applied to a number and a list returns the list with that many elements removed from the front. If the list has less than the required number of elements, drop returns []. Example

        drop 2 [1,2,3,4] = [3,4]

See also take.

> drop :: num->[*]->[*]  ||defined internally, as below

  drop (n+1) (a:x) = drop n x
  drop n x = x,                                         if integer n
           = error "drop applied to fractional number", otherwise

dropwhile applied to a predicate and a list, removes elements from the front of the list while the predicate is satisfied. Example:

        dropwhile digit "123gone" = "gone"

See also takewhile.

> dropwhile :: (*->bool)->[*]->[*]
> dropwhile f [] = []
> dropwhile f (a:x) = dropwhile f x, if f a
>                   = a:x,           otherwise

e is a transcendental number, the base of natural logarithms.

> e :: num
> e = exp 1

entier when applied to a number returns its integer part, meaning the largest integer not exceeding it. E.g.

        entier 1.0 = 1
        entier 3.5 = 3
        entier (-3.5) = -4.

Notice that for Miranda the number 1\' and the number1.0are different values - for example they yield different results under theinteger\' test. However 1=1.0 is True, because of the automatic conversion from integer to float.

> entier :: num->num  ||defined internally

A useful fact about entier, which relates it to the operators div and mod, is that the following law holds for any integers a, b with b\~=0 and a/b within the range for which integers can be represented exactly as fractional numbers

        a div b = entier (a/b)

error applied to a string creates an error value with the associated message. Error values are all equivalent to the undefined value - any attempt to access the value causes the program to terminate and print the string as a diagnostic.

> error :: [char]->*  ||defined internally

exp\' is the exponential function on real numbers. See alsolog`.

> exp :: num->num   ||defined internally

filemode applied to a string representing the pathname of a UNIX file, returns a string of length four giving the access permissions of the current process to the file. The permissions are encoded as (in this order) \"drwx\", any permission not granted is replaced by a \'-\' character. If there is no file at pathname p, filemode p returns the empty string. Example

        member (filemode f) 'w'

tests f for write permission. See also getenv\',read\', system.

> filemode :: [char]->[char]  ||defined internally

filter applied to a predicate and a list, returns a list containing only those elements that satisfy the predicate. Example

        filter (>5) [3,7,2,8,1,17] = [7,8,17]

> filter :: (*->bool)->[*]->[*]
> filter f x = [a | a<-x; f a]

foldl folds up a list, using a given binary operator and a given start value, in a left associative way. Example:

        foldl op r [a,b,c] = (((r $op a) $op b) $op c)

But note that in order to run in constant space, foldl forces op to evaluate its first parameter. See the definitions of product, reverse\',sum\' for examples of its use. See also foldr.

> foldl :: (*->**->*)->*->[**]->*  ||defined internally, as below

  foldl op r [] = r
  foldl op r (a:x) = strict (foldl op) (op r a) x
                     where
                     strict f x = seq x (f x)

WARNING - this definition of foldl differs from that in older versions of Miranda. The one here is the same as that in Bird and Wadler (1988). The old definition had the two args of op reversed. That is:-

        old_foldl op r = new_foldl (converse op) r

the function converse has been added to the standard environment.

foldl1 folds left over non-empty lists. See the definitions of max\',min` for examples of its use.

> foldl1 :: (*->*->*)->[*]->*  ||defined internally, as below

  foldl1 op (a:x) = foldl op a x
  foldl1 op [] = error "foldl1 applied to []"

foldr folds up a list, using a given binary operator and a given start value, in a right associative way. Example:

        foldr op r [a,b,c] = a $op (b $op (c $op r))

See the definitions of and\',concat\', or, for examples of its use.

> foldr :: (*->**->**)->**->[*]->** ||defined internally, as below

  foldr op r [] = r
  foldr op r (a:x) = op a (foldr op r x)

foldr1 folds right over non-empty lists.

> foldr1 :: (*->*->*)->[*]->*
> foldr1 op [a] = a
> foldr1 op (a:b:x) = op a (foldr1 op (b:x))
> foldr1 op [] = error "foldr1 applied to []"

force applied to any data structure, returns it, but forces a check that every part of the structure is defined. Example

        hd(force x)

returns the hd of x, but fully evaluates x first (so x must be finite). See also seq\'. Notice in particular the idiomseq (force a) bwhich returnsb\' but only after fully evaluating a.

> force :: *->* ||defined internally

fst\' returns the first component of a pair. See alsosnd`.

> fst :: (*,**)->*
> fst (a,b) = a

getenv\' looks up a string in the users UNIX environment. Example

        getenv  "HOME"

returns the pathname of your home directory. [If you want to see what else is in your UNIX environment, say printenv as a UNIX command.]

> getenv :: [char]->[char]   ||defined internally

hd applied to a non empty list, returns its first element. It is an error to apply hd\' to the empty list, \[\]. See alsotl`.

> hd :: [*]->*
> hd (a:x) = a
> hd [] = error "hd []"

hugenum is the largest fractional number that can exist in this implementation (should be around 1e308 for IEEE standard 64 bit floating point). See also tinynum.

> hugenum :: num  ||defined internally

id is the identity function - applied to any object it returns it.

> id :: *->*
> id x = x

index applied to a (finite or infinite) list, returns a list of its legal subscript values, in ascending order. E.g. index \"hippopotamus\" is [0,1,2,3,4,5,6,7,8,9,10,11].

> index :: [*]->[num]
> index x = f 0 x
>           where
>           f n [] = []
>           f n (a:x) = n:f(n+1)x

init\' is dual totl`, it returns a list without its last component. Example

        init [1,2,3,4] = [1,2,3].

See also last\'. \[Note, by thedual` of a list processing function we mean the function which does the same job in a world where all lists have been reversed.]

> init :: [*]->[*]
> init (a:x) = [],       if x=[]
>            = a:init x, otherwise
> init [] = error "init []"

integer is a predicate on numbers. True if and only if the number is not fractional.

> integer :: num->bool    ||defined internally

[iterate - iterate f x returns the infinite list [x, f x, f(f x), ... ] Example, iterate (2*) 1 yields a list of the powers of 2. In the definition note use of \", ..\" to express a recurrence relation (see manual section 13/2).]{#iterate}

> iterate :: (*->*)->*->[*]
> iterate f x = [y | y<-x, f y ..]

last applied to a non empty list returns its last element. This function is the dual of hd. Note that for any non-empty list x

        (init x ++ [last x]) = x

> last :: [*]->*    ||defined internally, as below

  last x = x!(#x-1)

lay applied to a list of strings, joins them together after appending a newline character to each string. Example

        lay ["hello","world"] = "hello\nworld\n"

Used to format output thus,

        lay(map show x)

as a top level expression, causes the elements of the list x to be printed one per line. See also layn\',lines`.

> lay :: [[char]]->[char]
> lay [] = []
> lay (a:x) = a++"\n"++lay x

layn\' is similar tolay`, but produces output with numbered lines.

> layn :: [[char]]->[char]
> layn x =   f 1 x
>            where
>            f n [] = []
>            f n (a:x) = rjustify 4 (show n) ++") "++a++"\n"++f (n+1) x

\'letter\' is a predicate on characters. True if the character is a letter.

> letter :: char->bool
> letter c = 'a'<=c<='z' \/ 'A'<=c<='Z'

limit applied to a list of values, returns the first value which is the same as its successor. Useful in testing for convergence. For example the following Miranda expression computes the square root of 2 by the Newton-Raphson method

        limit [x | x&lt;-2, 0.5*(x + 2/x).. ]

> limit :: [*]->*
> limit (a:b:x) = a,           if a=b
>               = limit (b:x), otherwise
> limit other = error "incorrect use of limit"

lines applied to a list of characters containing newlines, returns a list of lists, by breaking the original into lines. The newline characters are removed from the result. Example, lines applied to

        "hello world\nit's me,\neric\n"

returns [\"hello world\",\"it\'s me\",\"eric\"]. Note that lines treats newline as a terminator, not a separator (although it will tolerate a missing \'\n\' on the last line).

> lines :: [char]->[[char]]
> lines [] = []
> lines (a:x) = []:lines x,   if a='\n'
>             = (a:x1):xrest, otherwise
>               where 
>               (x1:xrest) = lines x, if x~=[]
>                          = []:[],   otherwise
>                            ||this handles missing '\n' on last line

Note that the inverse of lines\' is the functionlay, in that applyinglay\' to the output of lines will restore the original string (except that a final newline will be added, if missing in the original string).

ljustify applied to a number and a string, left justifies the string in a field of the specified width.

> ljustify :: num->[char]->[char]
> ljustify n s = s++spaces(n - # s)

log applied to a number returns its natural logarithm (i.e. logarithm to the base e). It is the inverse of the exponential function, exp. See also log10. Note that the log functions use a different algorithm when applied to integer arguments (rather than just converting to float first) so it is possible to take log, or log10, of very large integers.

> log :: num->num      ||defined internally

log10 applied to a number returns its logarithm to the base 10.

> log10 :: num->num      ||defined internally

map applied to a function and a list returns a copy of the list in which the given function has been applied to every element.

> map :: (*->**)->[*]->[**]
> map f x = [f a | a<-x]

map2\' is similar tomap, but takes a function of two arguments, and maps it along two argument lists. We could also definemap3,map4` etc., but they are much less often needed.

> map2 :: (*->**->***)->[*]->[**]->[***]
> map2 f x y = [f a b | (a,b)<-zip2 x y]

Note: the Bird and Wadler function zipwith is just an uncurried version of map2\', that iszipwith f (x,y)\' means map2 f x y.

max applied to a list returns the largest element under the built in ordering of \>. Examples

        max [1,2,12,-6,5] = 12
        max "hippopotamus" = 'u'

See also min\',sort`.

> max :: [*]->*
> max = foldl1 max2

max2 applied to two values of the same type returns the larger under the built in ordering of \'>\'. See also min2.

> max2 :: *->*->*
> max2 a b = a, if a>=b
>          = b, otherwise

member applied to a list and a value returns True or False as the value is or not present in the list.

> member :: [*]->*->bool
> member x a = or (map (=a) x)

merge applied to two sorted lists merges them to produce a single sorted result. Used to define sort, see later.

> merge :: [*]->[*]->[*]  ||defined internally, as below

  merge [] y = y
  merge (a:x) [] = a:x
  merge (a:x) (b:y) = a:merge x (b:y), if a<=b
                    = b:merge (a:x) y, otherwise

min\' applied to a list returns its least member under\<`.

> min :: [*]->*
> min = foldl1 min2

min2 applied to two values of the same type returns the smaller under the built in ordering of \'\<\'.

> min2 :: *->*->*
> min2 a b = b, if a>b
>          = a, otherwise

mkset applied to a list returns a copy of the list from which any duplicated elements have been removed. A list without duplications can be used to represent a set, whence the name. Works even on infinite list, but (beware) takes a time quadratic in the number of elements processed.

> mkset :: [*]->[*]
> mkset [] = []
> mkset (a:x) = a:filter (~=a) (mkset x)

neg is a function of one numeric argument, with the same action as the unary - operator.

> neg :: num->num
> neg x = -x

num is the type comprising both integer and fractional numbers (such as 42, -12.73e8).

        num :: type  ||primitive to Miranda

numval converts a numeric string to the corresponding number - can cope with sign, decimal point and scale factor (uses same rules as Miranda compiler). Strings containing inappropriate characters cause an error (exception - leading white space is harmless).

> numval :: [char]->num ||defined internally

or applied to a list of truthvalues, takes their logical disjunction.

> or :: [bool]->bool
> or = foldr (\/) False

pi is the well known real number (the ratio of the circumference of a circle to its diameter).

> pi :: num
> pi = 4*arctan 1

postfix takes an element and a list and adds the element to the end of the list. This is the dual of the prefix operator, :.

> postfix :: *->[*]->[*]
> postfix a x = x ++ [a]

product applied to list of numbers returns their product. See also sum.

> product :: [num]->num
> product = foldl (*) 1

read returns the contents of file with a given pathname. Provides an interface to the UNIX filing system. If the file is empty read returns [], but if the file does not exist, or lacks read permission, read\' causes an error. See alsofilemode\', getenv.

> read :: [char]->[char]  ||defined internally

readvals is a family of functions for reading a list of values from a file. See manual section 31/3.

rep applied to a number and a value, returns a list containing the specified number of instances of the value. (The name is short for replicate.) Example

        rep 6 'o' = "oooooo"

See also repeat.

> rep :: num->*->[*]
> rep n x = take n (repeat x)

repeat applied to a value returns an infinite list, all of whose elements are the given value.

> repeat :: *->[*]
> repeat x = xs
>            where xs = x:xs

reverse applied to any finite list returns a list of the same elements in reverse order.

> reverse :: [*]->[*]
> reverse = foldl (converse(:)) []

rjustify applied to a number and a string, right justifies the string in a field of the specified width.

> rjustify :: num->[char]->[char]
> rjustify n s = spaces(n - # s)++s

scan op r\' appliesfoldl op rto every initial segment of a list. For examplescan (+) 0 x` computes running sums.

> scan :: (*->**->*)->*->[**]->[*]
> scan op = g 
>           where
>           g r = (r:). rest
>                 where
>                 rest [] = []
>                 rest (a:x) = g (op r a) x

There is another way to explain scan, which makes it clearer why it is useful. Let s0 be the initial state of an automaton, and f::state->input->state, its state transition function - then `scan f s0\' is a function that takes a list of inputs for the automaton and returns the resulting list of states, starting with s0.

seq applied to two values, returns the second but checks that the first value is not completely undefined. Sometimes needed, e.g. to ensure correct synchronisation in interactive programs.

> seq :: *->**->** ||defined internally

show is a keyword denoting a family of functions for converting values of different types to their print representations. See manual section on show for more details.

shownum applied to a number returns as a string a standard print representation for it. A special case of the operator show. Applied to fractional numbers shownum gives 12 decimal places (less any trailing zeros), using a format appropriate to the size of number. For more detailed control over number format see showfloat, showscaled.

> shownum :: num->[char] ||defined internally,

showfloat p x returns as a string the number x printed in floating point format, that is in the form \"digits.digits\", where the integer p (>=0) gives the number of digits after the decimal point.

> showfloat :: num->num->[char] ||defined internally,

showscaled p x returns as a string the number x printed in scientific format, that is in the form \"n.nnnnnne[+/-]nn\", where the integer p (>=0) gives the number of digits required after the decimal point.

> showscaled :: num->num->[char] ||defined internally,

sin is the trigonometric sine function, argument in radians.

> sin :: num->num  ||defined internally

snd returns the second component of a pair.

> snd :: (*,**)->**
> snd (a,b) = b

sort applied to any finite list sorts the elements of the list into ascending order on the built in \'\<\' relation. Note that you cannot sort a list of functions. Example

        sort "hippopotamus" = "ahimoopppstu"

The following definition uses merge-sort, which has n log n worst-case behaviour.

> sort :: [*]->[*]
> sort x = x,                                         if n<=1
>        = merge (sort(take n2 x)) (sort(drop n2 x)), otherwise
>          where
>          n = # x
>          n2 = n div 2

spaces applied to a number returns a list of that many spaces.

> spaces :: num->[char]
> spaces n = rep n ' '

sqrt is the square root function on (integer or fractional) numbers. The result is always fractional.

> sqrt :: num->num   ||defined internally

subtract is a name for (converse) infix minus. Needed because you cannot form postsections in -\'. (See manual entry onsections`.) Example

        subtract 3

is the function that subtracts 3.

> subtract :: num->num->num
> subtract x y = y - x

sum applied to list of numbers returns their sum.

> sum :: [num]->num
> sum = foldl (+) 0

sys_message is an algebraic type containing a family of constructors used to control output to UNIX files. See manual section on Output to UNIX files for details.

> sys_message ::= Stdout [char] | Stderr [char] | Tofile [char] [char] |
>                 Closefile [char] | Appendfile [char] | System [char] |
>                 Exit num

system applied to a string causes the string to be executed as a UNIX shell command (by sh). The result returned is a 3-tuple, comprising the standard_output, error_output, and exit_status respectively, resulting from the execution of the UNIX command. See manual section on Input from UNIX files etc for more details.

> system :: [char]->([char],[char],num)  ||defined internally

take applied to a number and a list returns the specified number of elements from the front of the list. If the list has less than the required number of elements, take returns as many as it can get. Examples

        take 2 [1,2,3,4] = [1,2]
        take 7 "girls" = "girls"

> take :: num->[*]->[*]  ||defined internally, as below

  take (n+1) (a:x) = a : take n x
  take n x = [],                                        if integer n
           = error "take applied to fractional number", otherwise

takewhile applied to a predicate and a list, takes elements from the front of the list while the predicate is satisfied. Example: takewhile digit \"123gone\" = \"123\"

> takewhile :: (*->bool)->[*]->[*]
> takewhile f [] = []
> takewhile f (a:x) = a:takewhile f x, if f a
>                   = [],              otherwise

tinynum is the smallest positive fractional number that can be distinguished from zero in this implementation (should be around 1e-324 for IEEE standard 64 bit floating point).

> tinynum :: num  ||defined internally

tl applied to a non empty list returns the list without its first element. Example, tl \"snow\" is \"now\".

> tl :: [*]->[*]
> tl (a:x) = x
> tl [] = error "tl []"

transpose applied to a list of lists, returns their transpose (in the sense of matrix transpose - rows and columns are interchanged). Example

        transpose [[1,2,3],[4,5,6]] = [[1,4],[2,5],[3,6]]

The following definition is slightly more subtle than is at first sight necessary, in order to deal correctly with upper triangular matrices. Example

        transpose [[1,2,3],[4,5],[6]] = [[1,4,6],[2,5],[3]]

> transpose :: [[*]]->[[*]]
> transpose x = [],                             if x'=[]
>             = map hd x':transpose(map tl x'), otherwise
>               where
>               x' = takewhile (~=[]) x

It might be thought that this function belongs in a specialised library of matrix handling functions, but it has been found useful as a general purpose list processing function, whence its inclusion in the standard environment.

undef is a name for the completely undefined value. Any attempt access it results in an error message. Note that undef belongs to every type.

> undef :: *
> undef = error "undefined"

until applied to a predicate, a function and a value, returns the result of applying the function to the value the smallest number of times necessary to satisfy the predicate. Example

        until (>1000) (2*) 1 = 1024

> until :: (*->bool)->(*->*)->*->*
> until f g x = x,               if f x
>             = until f g (g x), otherwise

zip2 applied to two lists returns a list of pairs, formed by tupling together corresponding elements of the given lists. Example

        zip2 [0..3] "type" = [(0,'t'),(1,'y'),(2,'p'),(3,'e')]

This function is often useful in list comprehensions, where it provides an idiom for accessing two generators simultaneously. For example the following expression returns the scalar product of x and y (x,y::[num])

        sum [ a*b | (a,b) <- zip2 x y ]

> zip2 :: [*]->[**]->[(*,**)]  ||defined internally, as below

  zip2 (a:x) (b:y) = (a,b):zip2 x y
  zip2 x y = []

Note that if the lists being zipped are of different lengths, the length of the result is that of the shortest list (this holds for zip2 and all the following zip functions).

The function zip3 is analogous but takes three lists and returns a list of 3-tuples. Similarly for zip4\',zip5\', zip6 - zip functions above zip6 are not provided in the standard environment.

> zip3 (a:x) (b:y) (c:z) = (a,b,c):zip3 x y z
> zip3 x y z = []
> zip4 (a:w) (b:x) (c:y) (d:z) = (a,b,c,d):zip4 w x y z
> zip4 w x y z = []
> zip5 (a:v) (b:w) (c:x) (d:y) (e:z) = (a,b,c,d,e):zip5 v w x y z
> zip5 v w x y z = []
> zip6 (a:u)(b:v)(c:w)(d:x)(e:y)(f:z) = (a,b,c,d,e,f):zip6 u v w x y z
> zip6 u v w x y z = []

The following is included for compatibility with Bird and Wadler (1988). The normal Miranda style is to use the curried form zip2.

> zip :: ([*],[**])->[(*,**)]
> zip (x,y) = zip2 x y

End of definitions of the standard environment