I find myself writing things like
match f x with
| Some x' -> f' x'
| None ->
match g x with
| Some x' -> g' x'
| None ->
match h x with
| Some x' -> h' x'
| None ->
...
Is there a cleaner way to write this kind of code?
>Solution :
In your example, you can write a function that tries a list of alternatives:
let rec try_with alts x = match alts with
| [] -> None
| (pred, follow) :: rest ->
match pred x with
| Some x -> follow x
| None -> try_with rest x
...
try_with [f,f';g,g';h,h']
Alternatively, you can pattern match on tuples to test multiple patterns:
match f x, g x, h x with
| Some x, _, _ -> f' x
| _, Some x, _ -> g' x
| _, _, Some x -> h' x
And deep pattern matching is also possible (but doesn’t really match your example):
let f = function
| [ _; Either.Left [|x|]; Either.Right [_;_,_,y] ] -> x + y
| _ -> 0