12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667(**/**)type'aelem={content:'a;mutablenext:'acell}and'acell=Nil|Consof'aelemtype'at={mutablefirst:'aelem;mutablelast:'aelem}(* Create sentinel *)letcreate()=letsentinal={content=Obj.magic();next=Nil}in{first=sentinal;last=sentinal;}(** Returns the first elements that satisfies [pred] and removes it from the list. O(n) *)lettake~predt=letrecinner=function|Nil->None|Cons({content=_;next=Cons{content;next}}ascell)whenpredcontent->cell.next<-next;beginmatchnextwithNil->t.last<-cell|_->()end;Somecontent;|Cons{content=_;next}->innernextininner(Const.first)(** Peek at the first element without removing it from the list. O(1) *)letpeekt=matcht.first.nextwith|Nil->None|Cons{content;_}->Somecontent(** Pop the first element from the list. O(1) *)letpopt=matcht.first.nextwith|Nil->None|Cons{content;next}->t.first.next<-next;if(next=Nil)thent.last<-t.firstelse();Somecontent(** Removes and returns elements while statisfying [pred]. O(m), where m is number of elements returned *)lettake_while~predt=letrecinner=function|Nil->[]|Cons({content=_;next=Cons{content;next}}ascell)whenpredcontent->cell.next<-next;if(next=Nil)thent.last<-cellelse();content::innernext;|Cons_->[]ininner(Const.first)(** Prepends an element to the list *)letprependtv=lete={content=v;next=t.first.next}int.first.next<-Conse;if(e.next=Nil)thent.last<-eelse()(** Appends a element to the list *)letappendtv=lete={content=v;next=t.last.next}int.last.next<-Conse;t.last<-e(**/**)