123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107(*
* Olmi
*
* Copyright (C) 2015 Xavier Van de Woestyne <xaviervdw@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*)openOlmiInterfacesletidx=xletflipfxy=fyx(* Functors for monad implementation *)(* Using join interface *)moduleWithJoin(M:JOIN):BASIC_INTERFACEwithtype'at='aM.t=structincludeMletbindmf=join(fmapfm)end(* Using bind interface *)moduleWithBind(M:BIND):BASIC_INTERFACEwithtype'at='aM.t=structincludeMletjoinm=bindmidletfmapfm=bindm(funx->return(fx))end(* Functor for creating a complete monad *)moduleMonad(M:BASIC_INTERFACE):INTERFACEwithtype'at='aM.t=structincludeMlet(>>=)=bindlet(>|=)xf=fmapfxlet(>>)mn=m>>=(fun_->n)let(<=<)fg=funx->gx>>=flet(>=>)fg=flip(<=<)fglet(=<<)fx=flip(>>=)fxlet(<*>)fsms=fs>>=funf->ms>>=funx->return(fx)let(*>)x=(<*>)(fmap(fun_->id)x)let(<*)x_=(<*>)(return(funx->x))xlet(<**>)fx=flip(<*>)fxlet(<$>)=fmaplet(<$)v=fmap(fun_->v)letliftM=fmapletliftM2fm1m2=m1>>=funx->m2>>=funy->return(fxy)letliftM3fm1m2m3=m1>>=funx->m2>>=funy->m3>>=funz->return(fxyz)letliftM4fm1m2m3m4=m1>>=funx->m2>>=funy->m3>>=funz->m4>>=funa->return(fxyza)letliftM5fm1m2m3m4m5=m1>>=funx->m2>>=funy->m3>>=funz->m4>>=funa->m5>>=funb->return(fxyzab)letvoid_=return()end(* Functor for PLUS Monad *)modulePlus(M:BASIC_INTERFACE)(P:PLUSwithtype'at='aM.t):PLUS_INTERFACEwithtype'at='aM.t=structincludeMonad(M)letmempty=P.memptyletmplusab=P.mplusablet(<+>)=mplusletkeep_iffx=iffxthenreturnxelsememptyend