Interfaces for use with the match%optional
syntax, provided by ppx_optional
.
Idiomatic usage is to have a module M
like:
module M : sig
type t
module Optional_syntax : Optional_syntax.S
with type t := t
with type value := ...
end = struct
...
module Optional_syntax = struct
module Optional_syntax = struct
let is_none = is_none
let unsafe_value = unsafe_value
end
end
end
Then, uses look like:
let open M.Optional_syntax in
match%optional m with
| None -> ?
| Some v -> ?
The reason for the double module Optional_syntax
is so that open M.Optional_syntax
puts in scope only module Optional_syntax
; match%optional
then expands to
references to Optional_syntax.is_none
and Optional_syntax.unsafe_value
.
unsafe_value
does not have to be memory-safe if not guarded by is_none
.
Implementations of is_none
and unsafe_value
must not have any side effects.
More precisely, if you mutate any value currently being match'ed on (not necessarily
your own argument) you risk a segfault as well.
This is because match%optional
does not make any guarantee about is_none
call
being immediately followed by the corresponding unsafe_value
call. In fact it
makes several is_none
calls followed by several unsafe_value
calls, so in
the presence of side-effects by the time it makes an unsafe_value
call the result
of the corresponding is_none
can go stale.
For more details on the syntax extension, see ppx/ppx_optional/README.md
.
module type S = Optional_syntax_intf.S
module type S1 = Optional_syntax_intf.S1
module type S2 = Optional_syntax_intf.S2