diff6-10.chapter7.txt

このページは最後に更新されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

last mod. 2008-08-28 (木) 10:00:42

diff6-10

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.

新規 編集 添付