_B_a_s_i_c_ _t_y_p_e_ _s_t_r_u_c_t_u_r_e_ _a_n_d_ _n_o_t_a_t_i_o_n_ _f_o_r_ _t_y_p_e_s The Miranda programming language is _s_t_r_o_n_g_l_y _t_y_p_e_d - that is each expression and each variable has a type that can be deduced by a static analysis of the program text. _P_r_i_m_i_t_i_v_e_ _t_y_p_e_s num bool char Values of type `num' include both integer and floating point numbers, e.g. 23 0 -17 1.26e11 They are stored using different internal representations, but can be freely mixed in calculations, and are both of type `num' for type checking purposes. There is automatic conversion from integer to floating point when required (but not in the opposite direction - use `entier', see standard environment). Floating point numbers are held to double precision, integers to unbounded precision. The values of type `bool' are the two truth values: True False The values of type `char' are characters in the Latin-1 character set, e.g. 'a' '%' '\t' _L_i_s_t_ _t_y_p_e_s [t] is the type of lists whose elements are of type `t' Thus [num] is the type of lists of numbers such as [1,2,3,4,5] [[num]] is the type of lists of lists of numbers, such as [[1,2],[3,4]] [char] are lists of characters - this is also the type of string constants, so e.g. ['h','e','l','l','o'] and "hello" are interchangeable objects of this type. _T_u_p_l_e_ _t_y_p_e_s (t1,...,tn) is the type of a tuple with elements of type `t1' to `tn' Example - the value (1,True,"red") is of type (num,bool,[char]) The type of the empty tuple, `()', is also written `()'. Notice that tuples are distinguished from lists by being enclosed in parentheses, instead of square brackets. There is no concept of a 1-tuple, in Miranda, so the use of parentheses to enclose subexpressions, as in say a*(b+c), does not conflict with their use for tuple formation. _F_u_n_c_t_i_o_n_ _t_y_p_e_s t1->t2 is the type of a function with argument type `t1' and result type `t2' The '->' is right associative, so e.g. `num->num->num' is the type of a curried function of two numeric arguments. In addition to the built-in types described above, user defined types may be introduced - these are of three kinds, synonym types, algebraic types and abstract types - see separate manual entry for each. _I_m_p_l_i_c_i_t_ _t_y_p_i_n_g In Miranda the types of identifiers do NOT normally need to be declared explicitly - the compiler is able to infer the type of identifiers from their defining equations. For example if you write plural x = x ++ "s" the compiler will DEDUCE that `plural' is of type [char]->[char]. It is however permitted to include explicit type declarations in the script if desired, e.g. you could write (anywhere in the same script) plural :: [char]->[char] and the compiler will check this for consistency with the defining equation (the symbol `::' means `is of type'). More generally the type declared may be an _i_n_s_t_a_n_c_e (see below) of the type implied by the definition - in this case the effect of the declaration is to restrict the type of the identifier to be less general than it would otherwise have been. Note that only top-level identifiers may be the subject of type declarations, and that the type of an identifier may be declared at most once in a given script. _P_o_l_y_m_o_r_p_h_i_s_m The final feature of the type system is that it permits polymorphic types. There is an alphabet of generic type variables, written * ** *** etc. each of which stands for an arbitrary type. We give a simple example - the identity function, which may be defined id x = x is attributed the type `*->*'. This means that `id' has many types - `num->num', `char->char', `[[bool]]->[[bool]]' and so on - each of these is an instance of its most general type, `*->*'. Another simple example of polymorphism is the function `map' (see standard environment) which applies a function to every element of a list. For example `map integer [1,1.5,2]' is [True,False,True]. The type of map is map :: (*->**) -> [*] -> [**] The most polymorphic possible object is `undef', the identifier which stands for the undefined, or error value (undef is defined in the standard environment). Since every type has an undefined value, the correct type specification for undef is undef :: * Many of the functions in the standard environment have polymorphic types - the text of the standard environment (see separate manual entry) is therefore a useful source of examples.