123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227openBaseopenXlazytype'at='adesclazy_tand'adesc=|Consof'a*'at|Nullletnull=from_valNullletconsvt=from_val(Cons(v,t))let(^^)=consletsingletonv=consvnullletpeek=function|lazyNull->None|lazy(Cons(v,t))->Some(v,t)letis_null=function|lazyNull->true|_->falseletreccreatefst=lazy(matchfstwith|Some(v,st)->Cons(v,createfst)|None->Null)letrecof_list=function|[]->null|x::xs->consx(of_listxs)letto_listt=letrecto_listst=function|lazyNull->List.revst|lazy(Cons(v,t))->to_list(v::st)tinto_list[]tlethd=function|lazyNull->failwith"hd"|lazy(Cons(x,_))->xlettl=function|lazyNull->failwith"tl"|lazy(Cons(_,xs))->xsletrecnthtn=ifn<0theninvalid_arg"Stream.nth"elsematchtwith|lazyNull->failwith"Stream.nth"|lazy(Cons(x,xs))->ifn=0thenxelsenthxs(n-1)letrecinitt=lazy(matchtwith|lazyNull->failwith"Stream.init"|lazy(Cons(_,lazyNull))->Null|lazy(Cons(x,xs))->Cons(x,initxs))letreclength=function|lazyNull->0|lazy(Cons(_,xs))->lengthxs+1letreciterf=function|lazyNull->()|lazy(Cons(v,t))->fv;iterftletrecfold_leftfstt=lazy(matchtwith|lazyNull->!!st|lazy(Cons(v,t))->!!(fold_leftf(fstv)t))letrecfold_rightfxsst=lazy(matchxswith|lazyNull->Lazy.forcest|lazy(Cons(x,xs))->Lazy.force(fx(fold_rightfxsst)))letrecmapflst=lazy(matchlstwith|lazyNull->Null|lazy(Cons(v,lst'))->Cons(fv,mapflst'))letrecappendxsys=lazy(matchxswith|lazyNull->!!ys|lazy(Cons(x,xs))->Cons(x,appendxsys))letrevt=fold_left(funstx->x^^st)nulltletintersparseat=lazy(matchtwith|lazyNull->Null|lazy(Cons(_,lazyNull)assingleton)->singleton|lazy(Cons(x,xs))->Cons(x,from_val(Cons(a,xs))))letrecconcatxss=lazy(matchxsswith|lazyNull->Null|lazy(Cons(x,xs))->!!(appendx(concatxs)))letintercalatexsxss=concat(intersparsexsxss)(*
transpose :: [[a]] -> [[a]]Source
The transpose function transposes the rows and columns of its argument. For example,
transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
subsequences :: [a] -> [[a]]Source
The subsequences function returns the list of all subsequences of the argument.
subsequences "abc" == ["","a","b","ab","c","ac","bc","abc"]
permutations :: [a] -> [[a]]
*)letrecfold_left'fst=function|lazyNull->st|lazy(Cons(v,t))->fold_left'f(fvst)tletfold_left1ft=matchtwith|lazyNull->failwith"fold_left1"|lazy(Cons(v,t))->fold_leftfvtletrecfold_right1flstst=lazy(matchlstwith|lazyNull->failwith"fold_right1"|lazy(Cons(v,lazyNull))->v|lazy(Cons(v,lst))->Lazy.force(fv(fold_right1flstst)))letrecmemkt=matchtwith|lazyNull->false|lazy(Cons(v,t))->ifk=vthentrueelsememktletconcattss=lazy(matchtsswith|lazyNull->Null|lazy(Cons(ts,tss))->!!(appendts(concattss)))letfilterpxs=fold_right(funxst->ifpxthenconsxstelsest)xsnullletfilter_mappxs=fold_right(funxst->matchpxwith|None->st|Somex->consxst)xsnullletrectakenxs=lazy(ifn<=0thenNullelsematchxswith|lazyNull->Null|lazy(Cons(x,xs))->Cons(x,take(n-1)xs))(* [t2] must be a postfix of [t1] otherwise, it loops forever *)letrev_betweent1t2=letrecloopstt=ift==t2thenst(* CR jfuruse: we cannot always use pointer eq *)elsematchtwith|lazy(Cons(v,t'))->loop(v::st)t'|lazyNull->stinloop[]t1letbetweent1t2=List.rev(rev_betweent1t2)letsplit_atlent=letrecsplitrev_listlent=iflen<=0thenList.revrev_list,telsematchtwith|lazyNull->List.revrev_list,null|lazy(Cons(v,t))->split(v::rev_list)(len-1)tinsplit[]lent(*
let rec split_at' : int -> 'a t -> 'a t * 'a t = fun len t ->
let ztuple : ('a t * 'a t) Lazy.t = lazy (
if len <= 0 then null, t
else match t with
| lazy Null -> null, null
| lazy (Cons (v, t)) ->
let pref, post = split_at' (len-1) t in
v^^pref, post
)
in
lazy(!!(fst !!ztuple)),
lazy(!!(snd !!ztuple))
*)letrecsplit_at':int->'at->'at*'at=funlent->letztuple:('at*'at)Lazy.t=lazy(iflen<=0thennull,telsematchtwith|lazyNull->null,null|lazy(Cons(v,t))->letpref,post=split_at'(len-1)tinv^^pref,post)inlazy(!!(fst!!ztuple)),lazy(!!(snd!!ztuple))let_test_split_at'()=letreclist=function|0->null|i->lazy(print_inti;print_newline();Cons(i,list(i-1)))inletmy=split_at'3(list10)inprint_endline"forcing fst";ignore&Lazy.force(fstmy);print_endline"forcing snd";ignore&Lazy.force(sndmy);()(** {6 Monadic interface} *)includeMonad.Make(structtype'a_t='attype'at='a_tletreturna=singletonaletbindtf=concat(mapft)end)let%TESTfold_right_and_map_=letzeros=create(fun()->Some(0,()))()inletones=fold_right(funzst->(z+1)^^st)zerosnullinletones'=map(funz->z+1)zerosinassert(to_list(take3ones)=[1;1;1]);assert(to_list(take3ones')=[1;1;1])