mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
doc: update doc/containers, migrate it to mdx
This commit is contained in:
parent
404d74ac43
commit
b308680bee
3 changed files with 44 additions and 32 deletions
|
|
@ -546,7 +546,7 @@ Some structural types are used throughout the library:
|
|||
|
||||
### Extended Documentation
|
||||
|
||||
See [the extended documentation](doc/containers.adoc) for more examples.
|
||||
See [the extended documentation](doc/containers.md) for more examples.
|
||||
|
||||
</details>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
= OCaml-containers =
|
||||
:toc: macro
|
||||
:source-highlighter: pygments
|
||||
# More about OCaml-containers
|
||||
|
||||
This document contains more information on some modules of Containers.
|
||||
|
||||
toc::[]
|
||||
```ocaml
|
||||
# #require "containers";;
|
||||
```
|
||||
|
||||
== Hash combinators: `CCHash`
|
||||
## Hash combinators: `CCHash`
|
||||
|
||||
Although OCaml provides polymorphic hash tables (`('a,'b) Hashtbl.t`)
|
||||
using the polymorphic equality `(=)` and hash `Hashtbl.hash`, it is often
|
||||
|
|
@ -15,63 +15,67 @@ with custom equality and hash functions.
|
|||
|
||||
`CCHash` provides combinators for writing hash functions:
|
||||
|
||||
[source,OCaml]
|
||||
----
|
||||
```ocaml
|
||||
# module H = CCHash;;
|
||||
module H = CCHash
|
||||
|
||||
# let hash1 : (int * bool) list H.t = H.(list (pair int bool));;
|
||||
val hash1 : (int * bool) list H.t = <fun>
|
||||
```
|
||||
|
||||
```ocaml non-deterministic=output
|
||||
# hash1 [1, true; 2, false; 3, true];;
|
||||
- : int = 636041136
|
||||
|
||||
(* the function hashes the whole value, can be costly *)
|
||||
# hash1 CCList.(1 -- 1000 |> map (fun i->i, i mod 2 = 0));;
|
||||
- : int = 845685523
|
||||
# hash1 CCList.(1 -- 1001 |> map (fun i->i, i mod 2 = 0));;
|
||||
- : int = 381026697
|
||||
----
|
||||
```
|
||||
|
||||
The polymorphic hash function is still present, as `CCHash.poly`.
|
||||
The functions `CCHash.list_comm` and `CCHash.array_comm` allow to hash
|
||||
lists and arrays while ignoring the order of elements: all permutations
|
||||
of the input will have the same hash.
|
||||
|
||||
|
||||
|
||||
== Parser Combinator: `CCParse`
|
||||
:toc: macro
|
||||
:source-highlighter: pygments
|
||||
## Parser Combinator: `CCParse`
|
||||
|
||||
The module `CCParse` defines basic parser combinators on strings.
|
||||
Adapting https://github.com/inhabitedtype/angstrom#usage[angstrom's tutorial example] gives the following snippet.
|
||||
Adapting [angstrom's tutorial example](https://github.com/inhabitedtype/angstrom#usage)
|
||||
gives the following snippet.
|
||||
Note that backtracking is explicit in `CCParse`, hence
|
||||
the use of `try_` to allow it in some places.
|
||||
Explicit memoization with `memo` and `fix_memo` is also possible.
|
||||
|
||||
[source,OCaml]
|
||||
----
|
||||
open CCParse.Infix;;
|
||||
module P = CCParse;;
|
||||
```ocaml
|
||||
open CCParse.Infix
|
||||
module P = CCParse
|
||||
|
||||
let parens p = P.try_ (P.char '(') *> p <* P.char ')' ;;
|
||||
let add = P.char '+' *> P.return (+) ;;
|
||||
let sub = P.char '-' *> P.return (-) ;;
|
||||
let mul = P.char '*' *> P.return ( * ) ;;
|
||||
let div = P.char '/' *> P.return ( / ) ;;
|
||||
let parens p = P.try_ (P.char '(') *> p <* P.char ')'
|
||||
let add = P.char '+' *> P.return (+)
|
||||
let sub = P.char '-' *> P.return (-)
|
||||
let mul = P.char '*' *> P.return ( * )
|
||||
let div = P.char '/' *> P.return ( / )
|
||||
let integer =
|
||||
P.chars1_if (function '0'..'9'->true|_->false) >|= int_of_string ;;
|
||||
P.chars1_if (function '0'..'9'->true|_->false) >|= int_of_string
|
||||
|
||||
let chainl1 e op =
|
||||
P.fix (fun r ->
|
||||
e >>= fun x -> P.try_ (op <*> P.return x <*> r) <|> P.return x) ;;
|
||||
e >>= fun x -> P.try_ (op <*> P.return x <*> r) <|> P.return x)
|
||||
|
||||
let expr : int P.t =
|
||||
P.fix (fun expr ->
|
||||
let factor = parens expr <|> integer in
|
||||
let term = chainl1 factor (mul <|> div) in
|
||||
chainl1 term (add <|> sub)) ;;
|
||||
chainl1 term (add <|> sub))
|
||||
```
|
||||
|
||||
P.parse_string expr "4*1+2";; (* Ok 6 *)
|
||||
P.parse_string expr "4*(1+2)";; (* Ok 12 *)
|
||||
Now we can parse strings using `expr`:
|
||||
|
||||
```ocaml
|
||||
# P.parse_string expr "4*1+2";; (* Ok 6 *)
|
||||
- : int P.or_error = Result.Ok 6
|
||||
|
||||
# P.parse_string expr "4*(1+2)";; (* Ok 12 *)
|
||||
- : int P.or_error = Result.Ok 12
|
||||
```
|
||||
|
||||
----
|
||||
8
doc/dune
Normal file
8
doc/dune
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
(alias
|
||||
(name runtest)
|
||||
(deps containers.md)
|
||||
(action (progn
|
||||
(run mdx test %{deps})
|
||||
(diff? %{deps} %{deps}.corrected))))
|
||||
|
||||
Loading…
Add table
Reference in a new issue