123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452(*
* Tuples - functions for tuples
* Copyright (C) 2003 Nicolas Cannasse
* 2008 David Teller (Contributor)
* 2011 Ashish Agarwal
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version,
* with the special exception on linking described in file LICENSE.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)##V>=5##modulePervasives=StdlibmoduleTuple2=structtype('a,'b)t='a*'btype'aenumerable='a*'aletmakeab=(a,b)externalfirst:'a*'b->'a="%field0"externalsecond:'a*'b->'b="%field1"letswap(a,b)=(b,a)letmapfg(a,b)=leta=fain(a,gb)letmapnf(x,y)=(* force left-to-right evaluation order (this principle of least
surprise is already applied in stdlib's List.map) *)leta=fxin(a,fy)letmap1f(a,b)=(fa,b)letmap2f(a,b)=(a,fb)letcurryfxy=f(x,y)letuncurryf(x,y)=fxyletenum(x,y)=BatList.enum[x;y](* Makeefficient? *)letof_enume=matchBatEnum.getewithNone->failwith"Tuple2.of_enum: not enough elements"|Somex->matchBatEnum.getewithNone->failwith"Tuple2.of_enum: not enough elements"|Somey->(x,y)letprint?(first="(")?(sep=",")?(last=")")print_aprint_bout(a,b)=BatIO.nwriteoutfirst;print_a outa;BatIO.nwriteoutsep;print_boutb;BatIO.nwriteoutlastlet printn ?(first="(")?(sep=",")?(last=")")printeroutpair=print ~first~sep~last printerprinteroutpairlet compare ?(cmp1=Pervasives.compare)?(cmp2=Pervasives.compare)(a,b)(c,d)=letcomp=cmp1acinifcomp<>0thencompelsecmp2bdopenBatOrdleteqeq1eq2=fun(t1,t2)(t1',t2')->bin_eqeq1t1t1'eq2t2t2'letord ord1ord2=fun(t1,t2)(t1',t2')->bin_ordord1t1t1'ord2t2t2'letcomp comp1comp2 =fun(t1,t2)(t1',t2')->bin_compcomp1t1t1'comp2t2t2'moduleEq(A:Eq)(B:Eq)=structtypet=A.t*B.tleteq =eqA.eqB.eqendmoduleOrd(A:Ord)(B:Ord)=structtypet=A.t*B.tletord =ordA.ord B.ordendmoduleComp(A:Comp)(B:Comp)=structtypet=A.t*B.tletcompare =compA.compareB.compareendendmoduleTuple3=structtype('a,'b,'c)t='a*'b*'ctype'aenumerable='a*'a*'aletmakeabc=(a,b,c)letfirst(a,_,_)=aletsecond(_,b,_)=bletthird(_,_,c)=cletget12(a,b,_)=(a,b)letget13(a,_,c)=(a,c)letget23(_,b,c)=(b,c)letmapf1f2f3(a,b,c)=leta=f1ainletb=f2bin(a,b,f3c)letmapnf(a,b,c)=leta=fainletb=fbin(a,b,fc)letmap1f(a,b,c)=(fa,b,c)letmap2f(a,b,c)=(a,fb,c)letmap3f(a,b,c)=(a,b,fc)letcurryfabc=f(a,b,c)letuncurryf(a,b,c)=fabcletenum(a,b,c)=BatList.enum[a;b;c](* Makeefficient? *)letof_enume=matchBatEnum.getewithNone->failwith"Tuple3.of_enum: not enough elements"|Somea->matchBatEnum.getewithNone->failwith"Tuple3.of_enum: not enough elements"|Someb->matchBatEnum.getewithNone->failwith"Tuple3.of_enum: not enough elements"|Somec->(a,b,c)letprint?(first="(")?(sep=",")?(last=")")print_aprint_bprint_cout(a,b,c)=BatIO.nwriteoutfirst;print_a outa;BatIO.nwriteoutsep;print_boutb;BatIO.nwriteoutsep;print_coutc;BatIO.nwriteoutlastlet printn ?(first="(")?(sep=",")?(last=")")printeroutpair=print ~first~sep~last printerprinterprinteroutpairlet compare ?(cmp1=Pervasives.compare)?(cmp2=Pervasives.compare)?(cmp3=Pervasives.compare)(a1,a2,a3)(b1,b2,b3)=letc1=cmp1a1b1inifc1<>0thenc1elseletc2=cmp2a2b2inifc2<>0thenc2elsecmp3a3b3openBatOrdleteqeq1eq2eq3 =fun(t1,t2,t3)(t1',t2',t3')->bin_eqeq1t1t1'(bin_eqeq2t2t2'eq3)t3t3'letord ord1ord2ord3=fun(t1,t2,t3)(t1',t2',t3')->bin_ordord1t1t1'(bin_ordord2t2t2'ord3)t3t3'letcomp comp1comp2 comp3 =fun(t1,t2,t3)(t1',t2',t3')->bin_compcomp1t1t1'(bin_compcomp2t2t2'comp3)t3t3'moduleEq(A:Eq)(B:Eq)(C:Eq)=structtypet=A.t*B.t*C.tleteq =eqA.eqB.eqC.eqendmoduleOrd(A:Ord)(B:Ord)(C:Ord)=structtypet=A.t*B.t*C.tletord =ordA.ord B.ordC.ordendmoduleComp(A:Comp)(B:Comp)(C:Comp)=structtypet=A.t*B.t*C.tletcompare =compA.compareB.compareC.compareendendmoduleTuple4=structtype('a,'b,'c,'d)t='a*'b*'c*'dtype'aenumerable='a*'a*'a*'aletmakeabcd=(a,b,c,d)letfirst(a,_,_,_)=aletsecond(_,b,_,_)=bletthird(_,_,c,_)=cletfourth(_,_,_,d)=dletget12(a,b,_,_)=(a,b)letget13(a,_,c,_)=(a,c)letget14(a,_,_,d)=(a,d)letget23(_,b,c,_)=(b,c)letget24(_,b,_,d)=(b,d)letget34(_,_,c,d)=(c,d)letget123(a,b,c,_)=(a,b,c)letget124(a,b,_,d)=(a,b,d)letget234(_,b,c,d)=(b,c,d)letmapf1f2f3f4(a,b,c,d)=leta=f1ainletb=f2binletc=f3cin(a,b,c,f4d)letmapnf(a,b,c,d)=leta=fainletb=fbinletc=fcin(a,b,c,fd)letmap1f(a,b,c,d)=(fa,b,c,d)letmap2f(a,b,c,d)=(a,fb,c,d)letmap3f(a,b,c,d)=(a,b,fc,d)letmap4f(a,b,c,d)=(a,b,c,fd)letcurryfabcd=f(a,b,c,d)letuncurryf(a,b,c,d)=fabcdletenum(a,b,c,d)=BatList.enum[a;b;c;d](*Makeefficient? *)letof_enume=matchBatEnum.getewithNone->failwith"Tuple4.of_enum: not enough elements"|Somea->matchBatEnum.getewithNone->failwith"Tuple4.of_enum: not enough elements"|Someb->matchBatEnum.getewithNone->failwith"Tuple4.of_enum: not enough elements"|Somec->matchBatEnum.getewithNone->failwith"Tuple4.of_enum: not enough elements"|Somed->(a,b,c,d)letprint?(first="(")?(sep=",")?(last=")")print_aprint_bprint_cprint_dout(a,b,c,d)=BatIO.nwriteoutfirst;print_a outa;BatIO.nwriteoutsep;print_boutb;BatIO.nwriteoutsep;print_coutc;BatIO.nwriteoutsep;print_doutd;BatIO.nwriteoutlastlet printn ?(first="(")?(sep=",")?(last=")")printeroutpair=print ~first~sep~last printerprinterprinterprinteroutpairlet compare ?(cmp1=Pervasives.compare)?(cmp2=Pervasives.compare)?(cmp3=Pervasives.compare)?(cmp4=Pervasives.compare)(a1,a2,a3,a4)(b1,b2,b3,b4)=letc1=cmp1a1b1inifc1<>0thenc1elseletc2=cmp2a2b2inifc2<>0thenc2elseletc3=cmp3a3b3inifc3<>0thenc3elsecmp4a4b4openBatOrdleteqeq1eq2eq3 eq4 =fun(t1,t2,t3,t4)(t1',t2',t3',t4')->bin_eqeq1t1t1'(bin_eqeq2t2t2'(bin_eqeq3t3t3'eq4))t4t4'letord ord1ord2ord3ord4=fun(t1,t2,t3,t4)(t1',t2',t3',t4')->bin_ordord1t1t1'(bin_ordord2t2t2'(bin_ordord3t3t3'ord4))t4t4'letcomp comp1comp2 comp3 comp4 =fun(t1,t2,t3,t4)(t1',t2',t3',t4')->bin_compcomp1t1t1'(bin_compcomp2t2t2'(bin_compcomp3t3t3'comp4))t4t4'moduleEq(A:Eq)(B:Eq)(C:Eq)(D:Eq)=structtypet=A.t*B.t*C.t*D.tleteq =eqA.eqB.eqC.eqD.eqendmoduleOrd(A:Ord)(B:Ord)(C:Ord)(D:Ord)=structtypet=A.t*B.t*C.t*D.tletord =ordA.ord B.ordC.ordD.ordendmoduleComp(A:Comp)(B:Comp)(C:Comp)(D:Comp)=structtypet=A.t*B.t*C.t*D.tletcompare =compA.compareB.compareC.compareD.compareendendmoduleTuple5=structtype('a,'b,'c,'d,'e)t='a*'b*'c*'d*'etype'aenumerable='a*'a*'a*'a*'aletmakeabcde=(a,b,c,d,e)letfirst(a,_,_,_,_)=aletsecond(_,b,_,_,_)=bletthird(_,_,c,_,_)=cletfourth(_,_,_,d,_)=dletfifth(_,_,_,_,e)=eletget12(a,b,_,_,_)=(a,b)letget13(a,_,c,_,_)=(a,c)letget14(a,_,_,d,_)=(a,d)letget15(a,_,_,_,e)=(a,e)letget23(_,b,c,_,_)=(b,c)letget24(_,b,_,d,_)=(b,d)letget25(_,b,_,_,e)=(b,e)letget34(_,_,c,d,_)=(c,d)letget35(_,_,c,_,e)=(c,e)letget45(_,_,_,d,e)=(d,e)letget123(a,b,c,_,_)=(a,b,c)letget124(a,b,_,d,_)=(a,b,d)letget125(a,b,_,_,e)=(a,b,e)letget134(a,_,c,d,_)=(a,c,d)letget135(a,_,c,_,e)=(a,c,e)letget145(a,_,_,d,e)=(a,d,e)letget234(_,b,c,d,_)=(b,c,d)letget235(_,b,c,_,e)=(b,c,e)letget245(_,b,_,d,e)=(b,d,e)letget345(_,_,c,d,e)=(c,d,e)letget1234(a,b,c,d,_)=(a,b,c,d)letget1235(a,b,c,_,e)=(a,b,c,e)letget1245(a,b,_,d,e)=(a,b,d,e)letget1345(a,_,c,d,e)=(a,c,d,e)letget2345(_,b,c,d,e)=(b,c,d,e)letmapf1f2f3f4f5(a,b,c,d,e)=leta=f1ainletb=f2binletc=f3cinletd=f4din(a,b,c,d,f5e)letmapnf(a,b,c,d,e)=leta=fainletb=fbinletc=fcinletd=fdin(a,b,c,d,fe)letmap1f(a,b,c,d,e)=(fa,b,c,d,e)letmap2f(a,b,c,d,e)=(a,fb,c,d,e)letmap3f(a,b,c,d,e)=(a,b,fc,d,e)letmap4f(a,b,c,d,e)=(a,b,c,fd,e)letmap5f(a,b,c,d,e)=(a,b,c,d,fe)letcurryfabcde=f(a,b,c,d,e)letuncurryf(a,b,c,d,e)=fabcdeletenum(a,b,c,d,e)=BatList.enum[a;b;c;d;e](*Makeefficient? *)letof_enume=matchBatEnum.getewithNone->failwith"Tuple5.of_enum: not enough elements"|Somea->matchBatEnum.getewithNone->failwith"Tuple5.of_enum: not enough elements"|Someb->matchBatEnum.getewithNone->failwith"Tuple5.of_enum: not enough elements"|Somec->matchBatEnum.getewithNone->failwith"Tuple5.of_enum: not enough elements"|Somed->matchBatEnum.getewithNone->failwith"Tuple5.of_enum: not enough elements"|Somee->(a,b,c,d,e)letprint?(first="(")?(sep=",")?(last=")")print_aprint_bprint_cprint_dprint_eout(a,b,c,d,e)=BatIO.nwriteoutfirst;print_a outa;BatIO.nwriteoutsep;print_boutb;BatIO.nwriteoutsep;print_coutc;BatIO.nwriteoutsep;print_doutd;BatIO.nwriteoutsep;print_eoute;BatIO.nwriteoutlastlet printn ?(first="(")?(sep=",")?(last=")")printeroutpair=print ~first~sep~last printerprinterprinterprinterprinteroutpairlet compare ?(cmp1=Pervasives.compare)?(cmp2=Pervasives.compare)?(cmp3=Pervasives.compare)?(cmp4=Pervasives.compare)?(cmp5=Pervasives.compare)(a1,a2,a3,a4,a5)(b1,b2,b3,b4,b5)=letc1=cmp1a1b1inifc1<>0thenc1elseletc2=cmp2a2b2inifc2<>0thenc2elseletc3=cmp3a3b3inifc3<>0thenc3elseletc4=cmp4a4b4inifc4<>0thenc4elsecmp5a5b5openBatOrdleteqeq1eq2eq3 eq4 eq5 =fun(t1,t2,t3,t4,t5)(t1',t2',t3',t4',t5')->bin_eqeq1t1t1'(bin_eqeq2t2t2'(bin_eqeq3t3t3'(bin_eqeq4t4t4'eq5)))t5t5'letord ord1ord2ord3ord4ord5=fun(t1,t2,t3,t4,t5)(t1',t2',t3',t4',t5')->bin_ordord1t1t1'(bin_ordord2t2t2'(bin_ordord3t3t3'(bin_ordord4t4t4'ord5)))t5t5'letcomp comp1comp2 comp3 comp4 comp5 =fun(t1,t2,t3,t4,t5)(t1',t2',t3',t4',t5')->bin_compcomp1t1t1'(bin_compcomp2t2t2'(bin_compcomp3t3t3'(bin_compcomp4t4t4'comp5)))t5t5'moduleEq(A:Eq)(B:Eq)(C:Eq)(D:Eq)(E:Eq)=structtypet=A.t*B.t*C.t*D.t*E.tleteq =eqA.eqB.eqC.eqD.eqE.eqendmoduleOrd(A:Ord)(B:Ord)(C:Ord)(D:Ord)(E:Ord)=structtypet=A.t*B.t*C.t*D.t*E.tletord =ordA.ord B.ordC.ordD.ordE.ordendmoduleComp(A:Comp)(B:Comp)(C:Comp)(D:Comp)(E:Comp)=structtypet=A.t*B.t*C.t*D.t*E.tletcompare =compA.compareB.compareC.compareD.compareE.compareendend