mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-05-06 14:58:31 +00:00
Merge pull request #760 from dmbaturin/master
[ocaml/en] Syntax error fix and minor enhancements
This commit is contained in:
commit
814ac3d017
@ -8,10 +8,12 @@ OCaml is a strictly evaluated functional language with some imperative
|
|||||||
features.
|
features.
|
||||||
|
|
||||||
Along with StandardML and its dialects it belongs to ML language family.
|
Along with StandardML and its dialects it belongs to ML language family.
|
||||||
Just like StandardML, there are both a compiler and an interpreter
|
F# is also heavily influenced by OCaml.
|
||||||
for OCaml. The interpreter binary is normally called "ocaml" and
|
|
||||||
the compiler is "ocamlopt". There is also a bytecode compiler, "ocamlc",
|
Just like StandardML, OCaml features both an interpreter, that can be
|
||||||
but there are few reasons to use it.
|
used interactively, and a compiler.
|
||||||
|
The interpreter binary is normally called "ocaml" and the compiler is "ocamlopt".
|
||||||
|
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
|
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.
|
||||||
@ -29,7 +31,7 @@ val a : int = 99
|
|||||||
```
|
```
|
||||||
|
|
||||||
For a source file you can use "ocamlc -i /path/to/file.ml" command
|
For a source file you can use "ocamlc -i /path/to/file.ml" command
|
||||||
to print all names and signatures.
|
to print all names and type signatures.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ cat sigtest.ml
|
$ cat sigtest.ml
|
||||||
@ -45,7 +47,12 @@ val a : int
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note that type signatures of functions of multiple arguments are
|
Note that type signatures of functions of multiple arguments are
|
||||||
written in curried form.
|
written in curried form. A function that takes multiple arguments can be
|
||||||
|
represented as a composition of functions that take only one argument.
|
||||||
|
The "f(x,y) = x + y" function from the example above applied to
|
||||||
|
arguments 2 and 3 is equivalent to the "f0(y) = 2 + y" function applied to 3.
|
||||||
|
Hence the "int -> int -> int" signature.
|
||||||
|
|
||||||
|
|
||||||
```ocaml
|
```ocaml
|
||||||
(*** Comments ***)
|
(*** Comments ***)
|
||||||
@ -73,8 +80,15 @@ let foo = 1 ;;
|
|||||||
let foo' = foo * 2 ;;
|
let foo' = foo * 2 ;;
|
||||||
|
|
||||||
(* Since OCaml compiler infers types automatically, you normally don't 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. *)
|
specify argument types explicitly. However, you can do it if
|
||||||
let inc_int (x: int) = x + 1 ;;
|
you want or need to. *)
|
||||||
|
let inc_int (x: int) : int = x + 1 ;;
|
||||||
|
|
||||||
|
(* One of the cases when explicit type annotations may be needed is
|
||||||
|
resolving ambiguity between two record types that have fields with
|
||||||
|
the same name. The alternative is to encapsulate those types in
|
||||||
|
modules, but both topics are a bit out of scope of this
|
||||||
|
tutorial. *)
|
||||||
|
|
||||||
(* You need to mark recursive function definitions as such with "rec" keyword. *)
|
(* You need to mark recursive function definitions as such with "rec" keyword. *)
|
||||||
let rec factorial n =
|
let rec factorial n =
|
||||||
@ -136,6 +150,8 @@ x + y ;;
|
|||||||
works for non-recursive definitions too. *)
|
works for non-recursive definitions too. *)
|
||||||
let a = 3 and b = 4 in a * b ;;
|
let a = 3 and b = 4 in a * b ;;
|
||||||
|
|
||||||
|
(* Anonymous functions use the following syntax: *)
|
||||||
|
let my_lambda = fun x -> x * x ;;
|
||||||
|
|
||||||
(*** Operators ***)
|
(*** Operators ***)
|
||||||
|
|
||||||
@ -193,6 +209,10 @@ let bad_list = [1, 2] ;; (* Becomes [(1, 2)] *)
|
|||||||
(* You can access individual list items with the List.nth function. *)
|
(* You can access individual list items with the List.nth function. *)
|
||||||
List.nth my_list 1 ;;
|
List.nth my_list 1 ;;
|
||||||
|
|
||||||
|
(* There are higher-order functions for lists such as map and filter. *)
|
||||||
|
List.map (fun x -> x * 2) [1; 2; 3] ;;
|
||||||
|
List.filter (fun x -> if x mod 2 = 0 then true else false) [1; 2; 3; 4] ;;
|
||||||
|
|
||||||
(* You can add an item to the beginning of a list with the "::" constructor
|
(* You can add an item to the beginning of a list with the "::" constructor
|
||||||
often referred to as "cons". *)
|
often referred to as "cons". *)
|
||||||
1 :: [2; 3] ;; (* Gives [1; 2; 3] *)
|
1 :: [2; 3] ;; (* Gives [1; 2; 3] *)
|
||||||
@ -277,8 +297,8 @@ let l = Cons (1, EmptyList) ;;
|
|||||||
languages, but offers a lot more expressive power.
|
languages, but offers a lot more expressive power.
|
||||||
|
|
||||||
Even though it may look complicated, it really boils down to matching
|
Even though it may look complicated, it really boils down to matching
|
||||||
an argument against an exact value, a predicate, or a type constructor. The type system
|
an argument against an exact value, a predicate, or a type constructor.
|
||||||
is what makes it so powerful. *)
|
The type system is what makes it so powerful. *)
|
||||||
|
|
||||||
(** Matching exact values. **)
|
(** Matching exact values. **)
|
||||||
|
|
||||||
@ -289,7 +309,7 @@ let is_zero x =
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
(* Alternatively, you can use the "function" keyword. *)
|
(* Alternatively, you can use the "function" keyword. *)
|
||||||
let is_one x = function
|
let is_one = function
|
||||||
| 1 -> true
|
| 1 -> true
|
||||||
| _ -> false
|
| _ -> false
|
||||||
;;
|
;;
|
||||||
@ -320,8 +340,8 @@ say (Cat "Fluffy") ;; (* "Fluffy says meow". *)
|
|||||||
|
|
||||||
(* Recursive types can be traversed with pattern matching easily.
|
(* Recursive types can be traversed with pattern matching easily.
|
||||||
Let's see how we can traverse a datastructure of the built-in list type.
|
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
|
Even though the built-in cons ("::") looks like an infix operator,
|
||||||
a type constructor and can be matched like any other. *)
|
it's actually a type constructor and can be matched like any other. *)
|
||||||
let rec sum_list l =
|
let rec sum_list l =
|
||||||
match l with
|
match l with
|
||||||
| [] -> 0
|
| [] -> 0
|
||||||
|
Loading…
Reference in New Issue
Block a user