Last active
January 18, 2022 16:23
-
-
Save Leonidas-from-XIV/8d54d2756458ac7569112035e7a6ec3d to your computer and use it in GitHub Desktop.
A way to use the `let` operators to short-circuit a `fold`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* Some kind of function that needs to be [Some _] for the rest of the body *) | |
let bigger_than x v = match v > x with true -> Some (v - 1) | false -> None | |
(* Sample inputs *) | |
let xs = [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9 ] | |
(* Why `fold` here in the first place? Maybe your data structure doesn't have `filter_map` etc. | |
* This is an example | |
*) | |
(* the classic way is to match and evaluate to `acc` on every branch, nesting deeper and deeper *) | |
let classic xs = | |
List.fold_left | |
(fun acc x -> | |
match bigger_than 3 x with | |
| None -> acc | |
| Some condition1 -> ( | |
match bigger_than condition1 x with | |
| None -> acc | |
| Some condition2 -> condition2 :: acc)) | |
[] xs | |
let new_style xs = | |
List.fold_left | |
(fun acc x -> | |
(* instead, we define a custom operator that returns `acc` in the `None` case *) | |
let ( let* ) a f = match a with Some a -> f a | None -> acc in | |
let* condition1 = bigger_than 3 x in | |
let* condition2 = bigger_than condition1 x in | |
condition2 :: acc) | |
[] xs | |
(* of course the same is possible with operators like `>>=` but it is slightly more messy *) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment