123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)(** Module implementing basic combinators for OCaml option type.
It tries follow closely the style of OCaml standard library.
Actually, some operations have the same name as [List] ones:
they actually are similar considering ['a option] as a type
of lists with at most one element. *)(** [has_some x] is [true] if [x] is of the form [Some y] and [false]
otherwise. *)lethas_some=function|None->false|_->trueletis_empty=function|None->true|Some_->false(** Lifting equality onto option types. *)letequalfxy=matchx,ywith|None,None->true|Somex,Somey->fxy|_,_->falseletcomparefxy=matchx,ywith|None,None->0|Somex,Somey->fxy|None,Some_->-1|Some_,None->1lethashf=function|None->0|Somex->fxexceptionIsNone(** [get x] returns [y] where [x] is [Some y].
@raise IsNone if [x] equals [None]. *)letget=function|Somey->y|_->raiseIsNone(** [make x] returns [Some x]. *)letmakex=Somex(** [bind x f] is [f y] if [x] is [Some y] and [None] otherwise *)letbindxf=matchxwithSomey->fy|None->Noneletfilterfx=bindx(funv->iffvthenxelseNone)(** [init b x] returns [Some x] if [b] is [true] and [None] otherwise. *)letinitbx=ifbthenSomexelseNone(** [flatten x] is [Some y] if [x] is [Some (Some y)] and [None] otherwise. *)letflatten=function|Some(Somey)->Somey|_->None(** [append x y] is the first element of the concatenation of [x] and
[y] seen as lists. *)letappendo1o2=matcho1with|Some_->o1|None->o2(** {6 "Iterators"} ***)(** [iter f x] executes [f y] if [x] equals [Some y]. It does nothing
otherwise. *)letiterf=function|Somey->fy|_->()exceptionHeterogeneous(** [iter2 f x y] executes [f z w] if [x] equals [Some z] and [y] equals
[Some w]. It does nothing if both [x] and [y] are [None]. And raises
[Heterogeneous] otherwise. *)letiter2fxy=matchx,ywith|Somez,Somew->fzw|None,None->()|_,_->raiseHeterogeneous(** [map f x] is [None] if [x] is [None] and [Some (f y)] if [x] is [Some y]. *)letmapf=function|Somey->Some(fy)|_->None(** [fold_left f a x] is [f a y] if [x] is [Some y], and [a] otherwise. *)letfold_leftfa=function|Somey->fay|_->a(** [fold_left2 f a x y] is [f z w] if [x] is [Some z] and [y] is [Some w].
It is [a] if both [x] and [y] are [None]. Otherwise it raises
[Heterogeneous]. *)letfold_left2faxy=matchx,ywith|Somex,Somey->faxy|None,None->a|_->raiseHeterogeneous(** [fold_right f x a] is [f y a] if [x] is [Some y], and [a] otherwise. *)letfold_rightfxa=matchxwith|Somey->fya|_->a(** [fold_left_map f a x] is [a, f y] if [x] is [Some y], and [a] otherwise. *)letfold_left_mapfax=matchxwith|Somey->leta,z=fayina,Somez|_->a,Noneletfold_right_mapfxa=matchxwith|Somey->letz,a=fyainSomez,a|_->None,a(** [cata f a x] is [a] if [x] is [None] and [f y] if [x] is [Some y]. *)letcatafa=function|Somec->fc|None->a(** {6 More Specific operations} ***)(** [default a x] is [y] if [x] is [Some y] and [a] otherwise. *)letdefaulta=function|Somey->y|_->a(** {6 Smart operations} *)moduleSmart=struct(** [Smart.map f x] does the same as [map f x] except that it tries to share
some memory. *)letmapf=function|Someyasx->lety'=fyinify'==ythenxelseSomey'|_->Noneend(** {6 Operations with Lists} *)moduleList=struct(** [List.cons x l] equals [y::l] if [x] is [Some y] and [l] otherwise. *)letconsxl=matchxwith|Somey->y::l|_->l(** [List.flatten l] is the list of all the [y]s such that [l] contains
[Some y] (in the same order). *)letrecflatten=function|x::l->consx(flattenl)|[]->[]letmapfl=letrecauxfl=matchlwith|[]->[]|x::l->matchfxwith|None->raise_notraceExit|Somey->y::auxflintrySome(auxfl)withExit->Noneend