diff options
| author | Daniil Baturin <daniil@baturin.org> | 2014-09-10 21:33:41 +0700 | 
|---|---|---|
| committer | Daniil Baturin <daniil@baturin.org> | 2014-09-10 21:33:41 +0700 | 
| commit | 9f3bff9ce85ea95073f8a90397195c841d9fce23 (patch) | |
| tree | 17d4b789df9d03e9287425e295b2608907d09d0b /ocaml.html.markdown | |
| parent | 870289faa8083b496ad539d531529a64b66bf434 (diff) | |
Fix some typos/errors in the OCaml tutorial.
Diffstat (limited to 'ocaml.html.markdown')
| -rw-r--r-- | ocaml.html.markdown | 112 | 
1 files changed, 56 insertions, 56 deletions
| diff --git a/ocaml.html.markdown b/ocaml.html.markdown index ae862f08..3c9593d4 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -14,7 +14,7 @@ the compiler is "ocamlc.opt". There is also a bytecode compiler, "ocamlc",  but there are few reasons to use it.  It is strongly and statically typed, but instead of using manually written -type annotations it infers types of expressions using Hindley-Milner algorithm. +type annotations, it infers types of expressions using Hindley-Milner algorithm.  It makes type annotations unnecessary in most cases, but can be a major  source of confusion for beginners. @@ -46,24 +46,24 @@ Note that type signatures of functions of multiple arguments are  written in curried form.  ```ocaml +(*** Comments ***) +  (* Comments are enclosed in (* and *). It's fine to nest comments. *) -(* There are no single-line comments *) +(* There are no single-line comments. *) -(** Variables and functions *) +(*** Variables and functions ***) -(* Statements can be separated by double -   semicolon symbol, ";;". +(* Expressions can be separated by a double semicolon symbol, ";;".     In many cases it's redundant, but in this tutorial we use it after     every expression for easy pasting into the interpreter shell. *)  (* Variable and function declarations use "let" keyword. *)  let x = 10 ;; -(* Since OCaml uses type inference, you normally don't need to -   specify argument types explicitly. However, you can do it -   if you want or need to. *) +(* Since OCaml compiler infers types automatically, you normally don't need to +   specify argument types explicitly. However, you can do it if you want or need to. *)  let inc_int (x: int) = x + 1 ;;  (* You need to mark recursive function definitions as such with "rec" keyword. *) @@ -72,22 +72,13 @@ let rec factorial n =      else factorial n * factorial (n-1)  ;; -(* Function application usually doesn't need parantheses around arguments *) +(* Function application usually doesn't need parentheses around arguments *)  let fact_5 = factorial 5 ;; -(* ...unless the argument is an expression *) +(* ...unless the argument is an expression. *)  let fact_4 = factorial (5-1) ;;  let sqr2 = sqr (-2) ;; -(* You can use multiple statements separated by semicolon in function body, -   but the last expression becomes its return value. This is useful when -   writing in imperative style. The simplest form of it is inserting a  -   debug print. *) -let print_and_return x =  -    print_endline (string_of_int x); -    x -;; -  (* Every function must have at least one argument.     Since some funcions naturally don't take any arguments, there's      "unit" type for it that has the only one value written as "()" *) @@ -102,6 +93,15 @@ let make_inc x y = x + y ;; (* make_inc is int -> int -> int *)  let inc_2 = make_inc 2 ;;   (* inc_2 is int -> int *)  inc_2 3 ;; (* Evaluates to 5 *) +(* You can use multiple expressions in function body. +   The last expression becomes the return value. All other +   expressions must be of the "unit" type. +   This is useful when writing in imperative style, the simplest +   form of it is inserting a debug print. *) +let print_and_return x = +    print_endline (string_of_int x); +    x +;;  (* Since OCaml is a functional language, it lacks "procedures".     Every function must return something. So functions that @@ -117,7 +117,7 @@ let x = 10 in  let y = 20 in  x + y ;; -(* Alternatively you can use "let ... in and ..." construct. +(* Alternatively you can use "let ... and ... in" construct.     This is especially useful for mutually recursive functions,     with ordinary "let .. in" the compiler will complain about     unbound values. @@ -127,28 +127,28 @@ x + y ;;  let a = 3 and b = 4 in a * b ;; -(** Operators **) +(*** Operators ***)  (* There is little distintion between operators and functions.     Every operator can be called as a function. *)  (+) 3 4  (* Same as 3 + 4 *) -(* There's a number of built-in operators. One of unusual features is +(* There's a number of built-in operators. One unusual feature is     that OCaml doesn't just refrain from any implicit conversions     between integers and floats, it also uses different operators     for floats. *) -12 + 3 ;; (* Integer addition *) -12.0 +. 3.0 ;; (* Floating point addition *) +12 + 3 ;; (* Integer addition. *) +12.0 +. 3.0 ;; (* Floating point addition. *) -12 / 3 ;; (* Integer division *) -12.0 /. 3.0 ;; (* Floating point division *) -5 mod 2 ;; (* Remainder *) +12 / 3 ;; (* Integer division. *) +12.0 /. 3.0 ;; (* Floating point division. *) +5 mod 2 ;; (* Remainder. *)  (* Unary minus is a notable exception, it's polymorphic.     However, it also has "pure" integer and float forms. *)  - 3 ;; (* Polymorphic, integer *) -- 4.5 ;; (* Polymorphicm float *) +- 4.5 ;; (* Polymorphic, float *)  ~- 3 (* Integer only *)  ~- 3.4 (* Type error *)  ~-. 3.4 (* Float only *) @@ -156,34 +156,34 @@ let a = 3 and b = 4 in a * b ;;  (* You can define your own operators or redefine existing ones.     Unlike SML or Haskell, only selected symbols can be used     for operator names and first symbol defines associativity -   and precedence rules.  *) -let (+) a b = a - b ;; (* Surprise maintenance programmers *) +   and precedence rules. *) +let (+) a b = a - b ;; (* Surprise maintenance programmers. *)  (* More useful: a reciprocal operator for floats. -   Unary operators must start with "~" *) +   Unary operators must start with "~". *)  let (~/) x = 1.0 /. x ;;  ~/4.0 (* = 0.25 *) -(** Built-in datastructures *) +(*** Built-in datastructures ***)  (* Lists are enclosed in square brackets, items are separated by     semicolons. *)  let my_list = [1; 2; 3] ;; -(* Tuples are (optionally) enclosed in parantheses, items are separated -   by commas *) -let first_tuple = 3, 4 ;; +(* Tuples are (optionally) enclosed in parentheses, items are separated +   by commas. *) +let first_tuple = 3, 4 ;; (* Has type "int * int". *)  let second_tuple = (4, 5) ;;  (* Corollary: if you try to separate list items by commas, you get a list     with a tuple inside, probably not what you want. *)  let bad_list = [1, 2] ;; (* Becomes [(1, 2)] *) -(* You can access individual list items with List.nth function *) +(* You can access individual list items with the List.nth function. *)  List.nth my_list 1 ;; -(* You can add an item to the beginning of a list with "::" constructor +(* You can add an item to the beginning of a list with the "::" constructor     often referred to as "cons". *)  1 :: [2; 3] ;; (* Gives [1; 2; 3] *) @@ -195,20 +195,20 @@ my_array.(0) ;; -(** Data types *) +(*** User-defined data types ***) -(* You can define types with "type some_type =" construct. Like in this +(* You can define types with the "type some_type =" construct. Like in this     useless type alias: *)  type my_int = int ;;  (* More interesting types include so called type constructors.     Constructors must start with a capital letter. *)  type ml = OCaml | StandardML ;; -let lang = OCaml ;;  (* Has type "ml" *) +let lang = OCaml ;;  (* Has type "ml". *)  (* Type constructors don't need to be empty. *)  type my_number = PlusInfinity | MinusInfinity | Real of float ;; -let r0 = Real -3.4 ;; (* Has type "my_number" *) +let r0 = Real (-3.4) ;; (* Has type "my_number". *)  (* Can be used to implement polymorphic arithmetics. *)  type number = Int of int | Float of float ;; @@ -222,13 +222,13 @@ let my_point = Point (2.0, 3.0) ;;  type 'a list_of_lists = 'a list list ;;  type int_list_list = int list_of_lists ;; -(* Types also can be recursive. Like in this type analogous to +(* Types can also be recursive. Like in this type analogous to     built-in list of integers. *)  type my_int_list = EmptyList | IntList of int * my_int_list ;;  let l = Cons (1, EmptyList) ;; -(** Pattern matching *) +(*** Pattern matching ***)  (* Pattern matching is somewhat similar to switch statement in imperative     languages, but offers a lot more expressive power. @@ -237,20 +237,21 @@ let l = Cons (1, EmptyList) ;;     an argument against an exact value, a predicate, or a type constructor. The type system     is what makes it so powerful. *) -(* Matching exact values. "_" means "anything" *) +(** Matching exact values.  **) +  let is_zero x =      match x with      | 0 -> true -    | _ -> false +    | _ -> false  (* The "_" pattern means "anything else". *)  ;; -(* Alternatively, you can use "function" keyword *) +(* Alternatively, you can use the "function" keyword. *)  let is_one x = function  | 1 -> true  | _ -> false  ;; -(* Matching predicates, aka "guarded pattern matching" *) +(* Matching predicates, aka "guarded pattern matching". *)  let abs x =       match x with      | x when x < 0 -> -x @@ -260,7 +261,7 @@ let abs x =  abs 5 ;; (* 5 *)  abs (-5) (* 5 again *) -(* Matching type constructors *) +(** Matching type constructors **)  type animal = Dog of string | Cat of string ;; @@ -270,24 +271,23 @@ let say x =      | Cat x -> x ^ " says meow"  ;; -say (Cat "Fluffy") ;; (* "Fluffy says meow" *) +say (Cat "Fluffy") ;; (* "Fluffy says meow". *) -(* Traversing data structures *) +(** Traversing datastructures with pattern matching **)  (* Recursive types can be traversed with pattern matching easily. -   The cons thing ("::") that is used with built-in lists is actually a -   type constructor, except it can be used in infix form, unlike  -   user-defined constructors. So you can use it like this: *) - +   Let's see how we can traverse a datastructure of the built-in list type. +   Even though the built-in cons ("::") looks like an infix operator, it's actually +   a type constructor and can be matched like any other. *)  let rec sum_list l =      match l with      | [] -> 0      | head :: tail -> head + (sum_list tail)  ;; -sum_list [1; 2; 3] ;; +sum_list [1; 2; 3] ;; (* Evaluates to 6 *) -(* Built-int syntax for cons obscures the structure a bit, so we'll make +(* Built-in syntax for cons obscures the structure a bit, so we'll make     our own list for demonstration. *)  type int_list = Nil | Cons of int * int_list ;; | 
