diff6-10.chapter7.txtこのページは最後に更新されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。 last mod. 2008-08-28 (木) 10:00:42
4c4 < This chapter describes syntactic extensions and convenience features that are --- > This chapter describes language extensions and convenience features that are 9c9,24 < 7.1 Streams and stream parsers --- > 7.1 Integer literals for types int32, int64 and nativeint > *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= > > > int32-literal ::= integer-literal l > > int64-literal ::= integer-literal L > > nativeint-literal ::= integer-literal n > An integer literal can be followed by one of the letters l, L or n to > indicate that this integer has type int32, int64 or nativeint respectively, > instead of the default type int for integer literals. The library modules > Int32[], Int64[] and Nativeint[] provide operations on these integer types. > > > 7.2 Streams and stream parsers 13,18c28,88 < Streams and stream parsers are no longer part of the Objective Caml language, < but available through a CamlP4 syntax extension. See the CamlP4 reference < manual for more information. Objective Caml programs that use streams and < stream parsers can be compiled with the -pp camlp4o option to ocamlc and < ocamlopt. For interactive use, run ocaml and issue the `#load "camlp4o.cma";;' < command. --- > The syntax for streams and stream parsers is no longer part of the Objective > Caml language, but available through a Camlp4 syntax extension. See the Camlp4 > reference manual for more information. Support for basic operations on streams > is still available through the Stream[] module of the standard library. > Objective Caml programs that use the stream parser syntax should be compiled > with the -pp camlp4o option to ocamlc and ocamlopt. For interactive use, run > ocaml and issue the `#load "camlp4o.cma";;' command. > > > 7.3 Recursive definitions of values > *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= > > > As mentioned in section 6.7.1, the let rec binding construct, in addition to > the definition of recursive functions, also supports a certain class of > recursive definitions of non-functional values, such as > let rec name_1 = 1 :: name_2 and name_2 = 2 :: name_1 in expr > which binds name_1 to the cyclic list 1::2::1::2::..., and name_2 to the > cyclic list 2::1::2::1::...Informally, the class of accepted definitions > consists of those definitions where the defined names occur only inside > function bodies or as argument to a data constructor. > More precisely, consider the expression: > let rec name_1 = expr_1 and ... and name_n = expr_n in expr > It will be accepted if each one of expr_1 ... expr_n is statically > constructive with respect to name_1 ... name_n and not immediately linked to > any of name_1 ... name_n > An expression e is said to be statically constructive with respect to the > variables name_1 ... name_n if at least one of the following conditions is > true: > > - e has no free occurrence of any of name_1 ... name_n > - e is a variable > - e has the form fun ... -> ... > - e has the form function ... -> ... > - e has the form lazy ( ... ) > - e has one of the following forms, where each one of expr_1 ... expr_m is > statically constructive with respect to name_1 ... name_n, and expr_0 is > statically constructive with respect to name_1 ... name_n, xname_1 ... > xname_m: > > - let [rec] xname_1 = expr_1 and ... and xname_m = expr_m in expr_0 > - let module ... in expr_1 > - constr ( expr_1, ... , expr_m) > - `tag-name ( expr_1, ... , expr_m) > - [| expr_1; ... ; expr_m |] > - { field_1 = expr_1; ... ; field_m = expr_m } > - { expr_1 with field_2 = expr_2; ... ; field_m = expr_m } where expr_1 > is not immediately linked to name_1 ... name_n > - ( expr_1, ... , expr_m ) > - expr_1; ... ; expr_m > > > An expression e is said to be immediately linked to the variable name in the > following cases: > > - e is name > - e has the form expr_1; ... ; expr_m where expr_m is immediately linked to > name > - e has the form let [rec] xname_1 = expr_1 and ... and xname_m = expr_m in > expr_0 where expr_0 is immediately linked to name or to one of the xname_i > such that expr_i is immediately linked to name. 21c91,92 < 7.2 Range patterns --- > > 7.4 Range patterns 33c104 < 7.3 Assertion checking --- > 7.5 Assertion checking 46,47c117,118 < 7.4 Deferred computations < *=*=*=*=*=*=*=*=*=*=*=*=*= --- > 7.6 Lazy evaluation > *=*=*=*=*=*=*=*=*=*= 55,56c126,127 < information, see the description of module Lazy in the standard library < (section 20.15). --- > information, see the description of module Lazy in the standard library (see > section 20.15). 59c130 < 7.5 Local modules --- > 7.7 Local modules 63,64c134,135 < The expression let module module-name = module-expr in expr locally binds the < module expression module-expr to the identifier module-name during the --- > The expression let module module-name = module-expr in expr locally binds > the module expression module-expr to the identifier module-name during the 67,68c138 < << < let remove_duplicates comparison_fun string_list = --- > << let remove_duplicates comparison_fun string_list = 78,79c148,149 < 7.6 Grouping in integer and floating-point literals < *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= --- > 7.8 Private types > *=*=*=*=*=*=*=*=*= 82,84c152,290 < In integer and floating-point literals, the character _ (underscore) can be < used to separate groups of digits, as in 1_000_000, 0x45_FF, or 1_234.567_89. < The underscore characters are simply ignored when reading the literal. --- > type-representation ::= ... > | = private constr-decl { | constr-decl } > | = private { field-decl { ; field-decl } } > Private types are variant or record types. Values of these types can be > de-structured normally in pattern-matching or via the expr . field notation > for record accesses. However, values of these types cannot be constructed > directly by constructor application or record construction. Moreover, > assignment on a mutable field of a private record type is not allowed. > The typical use of private types is in the export signature of a module, to > ensure that construction of values of the private type always go through the > functions provided by the module, while still allowing pattern-matching outside > the defining module. For example: > << module M : sig > type t = private A | B of int > val a : t > val b : int -> t > end > = struct > type t = A | B of int > let a = A > let b n = assert (n > 0); B n > end > >> > Here, the private declaration ensures that in any value of type M.t, the > argument to the B constructor is always a positive integer. > With respect to the variance of their parameters, private types are handled > like abstract types. That is, if a private type has parameters, their variance > is the one explicitly given by prefixing the parameter by a `+' or a `-', it is > invariant otherwise. > > > 7.9 Recursive modules > *=*=*=*=*=*=*=*=*=*=*= > > > definition ::= ... > > | module rec module-name : module-type = module-expr { > and module-name: module-type = module-expr } > > > specification ::= ... > > | module rec module-name : module-type { and module-name: > module-type } > > Recursive module definitions, introduced by the 'module rec' ...'and' ... > construction, generalize regular module definitions module module-name = > module-expr and module specifications module module-name : module-type by > allowing the defining module-expr and the module-type to refer recursively to > the module identifiers being defined. A typical example of a recursive module > definition is: > << module rec A : sig > type t = Leaf of string | Node of ASet.t > val compare: t -> t -> int > end > = struct > type t = Leaf of string | Node of ASet.t > let compare t1 t2 = > match (t1, t2) with > (Leaf s1, Leaf s2) -> Pervasives.compare s1 s2 > | (Leaf _, Node _) -> 1 > | (Node _, Leaf _) -> -1 > | (Node n1, Node n2) -> ASet.compare n1 n2 > end > and ASet : Set.S with type elt = A.t > = Set.Make(A) > >> > It can be given the following specification: > << module rec A : sig > type t = Leaf of string | Node of ASet.t > val compare: t -> t -> int > end > and ASet : Set.S with type elt = A.t > >> > > This is an experimental extension of Objective Caml: the class of recursive > definitions accepted, as well as its dynamic semantics are not final and > subject to change in future releases. > Currently, the compiler requires that all dependency cycles between the > recursively-defined module identifiers go through at least one "safe" module. A > module is "safe" if all value definitions that it contains have function types > typexpr_1 -> typexpr_2. Evaluation of a recursive module definition proceeds > by building initial values for the safe modules involved, binding all > (functional) values to fun _ -> raise Undefined_recursive_module. The defining > module expressions are then evaluated, and the initial values for the safe > modules are replaced by the values thus computed. If a function component of a > safe module is applied during this computation (which corresponds to an > ill-founded recursive definition), the Undefined_recursive_module exception is > raised. > > > 7.10 Private row types > *=*=*=*=*=*=*=*=*=*=*=* > > > type-equation ::= ... > | = private typexpr > Private row types are type abbreviations where part of the structure of the > type is left abstract. Concretely typexpr in the above should denote either an > object type or a polymorphic variant type, with some possibility of refinement > left. If the private declaration is used in an interface, the corresponding > implementation may either provide a ground instance, or a refined private type. > << module M : sig type c = private < x : int; .. > val o : c end = > struct > class c = object method x = 3 method y = 2 end > let o = new c > end > >> > This declaration does more than hiding the y method, it also makes the type c > incompatible with any other closed object type, meaning that only o will be of > type c. In that respect it behaves similarly to private record types. But > private row types are more flexible with respect to incremental refinement. > This feature can be used in combination with functors. > << module F(X : sig type c = private < x : int; .. > end) = > struct > let get_x (o : X.c) = o#x > end > module G(X : sig type c = private < x : int; y : int; .. > end) = > struct > include F(X) > let get_y (o : X.c) = o#y > end > >> > > Polymorphic variant types can be refined in two ways, either to allow the > addition of new constructors, or to allow the disparition of declared > constructors. The second case corresponds to private variant types (one cannot > create a value of the private type), while the first case requires default > cases in pattern-matching to handle addition. > << type t = [ `A of int | `B of bool ] > type u = private [< t > `A ] > type v = private [> t ] > >> > With type u, it is possible to create values of the form (`A n), but not (`B > b). With type v, construction is not restricted but pattern-matching must have > a default case. > Like for abstract and private types, the variance of type parameters is not > infered, and must be given explicitly. |