diff --git a/README.md b/README.md index 7961c74..912e8b5 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ This has been heavily inspired by the [Rust Cookbook](https://brson.github.io/ru * [Js.Dict](#jsdict) * [Associative list](#associative-list) * [Hashtbl](#hashtbl) + * [Belt.HashMap](#belthashmap) + [Use a Set in a recursive type](#use-a-set-in-a-recursive-type) * [Promises](#promises) + [Creating new Promises](#creating-new-promises) @@ -182,8 +183,10 @@ let () = Use [Random module](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Random.html) to generate random numbers ```ml -let () = - Js.log (Random.int 5) +(* To make sure you have a different seed when your program runs each time *) +let () = Random.init (Js.Date.now () |> int_of_float) + +let () = Random.int 5 |> Js.log ``` #### Log a message to the console @@ -239,7 +242,6 @@ let () = | None -> Js.log "no matches" ``` - Or using [bs-revamp](https://github.com/glennsl/bs-revamp) with the same input: ```ml @@ -269,6 +271,31 @@ let () = *) ``` +or use `Js.String` + +```ml +let code = {| + let borderLeftColor = "borderLeftColor"; + let borderRightColor = "borderRightColor"; +|} + +let matchLetter letter _ _ = "-" ^ (Js.String.toLowerCase letter) + +let matchLiterals _ p1 _ _ = + let t = Js.String.unsafeReplaceBy0 [%re "/[A-Z]/g"] matchLetter p1 in {j|"$t"|j} + +let () = + code + |> Js.String.unsafeReplaceBy1 [%re "/\"([^\"]*)\"/g"] matchLiterals + |> Js.log + + +(* Outputs: + let borderLeftColor = "border-left-color"; + let borderRightColor = "border-right-color"; +*) +``` + #### Create a map data structure, add or replace an entry, and print each key/value pair ###### Map @@ -370,6 +397,36 @@ let () = painIndexMap |> Hashtbl.iter (fun k v -> Js.log {j|key:$k, val:$v|j}) ``` +###### Belt.HashMap + +Use a generic `Belt.HashMap` to demo a mutable hash map with string type key. In fact, You can use `Belt.HashMap.String` instead. + +```ml +open Belt +module StrHash = + Id.MakeHashable(struct + type t = string + let hash = String.length + let eq = (=) + end) + +let painIndexMap = HashMap.make ~hintSize:10 ~id:(module StrHash) +let () = + let open HashMap in + set painIndexMap "western paper wasp" 1.0; + set painIndexMap "yellowjacket" 2.0; + set painIndexMap "honey bee" 2.0; + set painIndexMap "red paper wasp" 3.0; + set painIndexMap "tarantula hawk" 4.0; + set painIndexMap "bullet ant" 4.0 + +let () = HashMap.set painIndexMap "bumble bee" 2.0 + +let () = + HashMap.forEach painIndexMap + @@ fun k v -> Js.log {j|key:$k, val:$v|j} +``` + #### Use a Set in a recursive type The task is to make something like this using Set: @@ -432,7 +489,7 @@ let timer = accidentally partially apply the function *) let _ : Js.Global.timeoutId = Js.Global.setTimeout - (fun () -> (resolve "Done!")[@bs]) + (fun () -> (resolve "Done!")[@bs]) 1000 in () ) @@ -452,7 +509,7 @@ let _ : unit Js.Promise.t = (* Chaining *) let _ : unit Js.Promise.t = Js.Promise.then_ - (fun value -> Js.Promise.resolve (Js.log value)) + (fun value -> Js.Promise.resolve (Js.log value)) (Js.Promise.then_ (fun value -> Js.Promise.resolve (value + 1)) (Js.Promise.resolve 1)) @@ -474,7 +531,7 @@ let _ : unit Js.Promise.t = let open Js.Promise in all2 (resolve 1, resolve "a") |> then_ (fun (v1, v2) -> - Js.log ("Value 1: " ^ string_of_int v1); + Js.log ("Value 1: " ^ string_of_int v1); Js.log ("Value 2: " ^ v2); resolve ()) @@ -514,20 +571,20 @@ let _ : unit Js.Promise.t = * In general, we should not rely on rejecting/catching errors for control flow; * it's much better to use a `result` type instead. *) -let betterOk : (string, _) Js.Result.t Js.Promise.t = +let betterOk : (string, _) Belt.Result.t Js.Promise.t = Js.Promise.make (fun ~resolve ~reject:_ -> - resolve (Js.Result.Ok ("everything's fine")) [@bs]) + resolve (Belt.Result.Ok ("everything's fine")) [@bs]) -let betterOhNo : (_, string) Js.Result.t Js.Promise.t = +let betterOhNo : (_, string) Belt.Result.t Js.Promise.t = Js.Promise.make (fun ~resolve ~reject:_ -> - resolve (Js.Result.Error ("nope nope nope")) [@bs]) + resolve (Belt.Result.Error ("nope nope nope")) [@bs]) let handleResult = Js.Promise.then_ (fun result -> Js.Promise.resolve ( match result with - | Js.Result.Ok text -> Js.log ("OK: " ^ text) - | Js.Result.Error reason -> Js.log ("Oh no: " ^ reason))) + | Belt.Result.Ok text -> Js.log ("OK: " ^ text) + | Belt.Result.Error reason -> Js.log ("Oh no: " ^ reason))) let _ : unit Js.Promise.t = handleResult betterOk @@ -713,8 +770,8 @@ external withAsyncCallback : ((Js.Json.t -> unit) -> unit) -> unit = "" [@@bs.va let withAsyncCallback: (doneFn -> unit) -> unit = fun f -> withAsyncCallback (fun done_ -> - f (function | Some value -> value |> Js.Json.string |> done_ - | None -> Js.false_ |> Js.Json.boolean |> done_)) + f (function | Some value -> value |> Js.Json.string |> done_ + | None -> false |> Js.Json.boolean |> done_)) ``` @@ -774,7 +831,6 @@ let () = ## Node-specific #### Read lines from a text file -Uses [bs-node](https://github.com/reasonml-community/bs-node) ```ml let () = Node.Fs.readFileAsUtf8Sync "README.md" @@ -783,7 +839,7 @@ let () = ``` #### Read and parse a JSON file -Uses [bs-json](https://github.com/reasonml-community/bs-json) and [bs-node](https://github.com/reasonml-community/bs-node) +Uses [bs-json](https://github.com/reasonml-community/bs-json) ```ml let decodeName text = Js.Json.parseExn text @@ -804,11 +860,10 @@ let () = ``` #### Run an external command -Uses [bs-node](https://github.com/reasonml-community/bs-node) ```ml let () = (* prints node's version *) - Node.(ChildProcess.execSync "node -v" (Options.options ~encoding:"utf8" ())) + Node.(Child_process.execSync "node -v" (Child_process.option ~encoding:"utf8" ())) |> Js.log ```