Catenable lists are lists with efficient (constant-time) appending, \(O(1)\) time complexity, like difference lists, and additional
operations. We were taught that they are widely used to implement text processing systems such as text editors, where
characters and text fragments need to be inserted and deleted efficiently, which is why arrays holding
the text are not used.
but ye it makes sense, if a is empty then just returns b no matter what, and if b is empty returns a nomatter what and if they not empty then returns them both appended
letmap(f:'a->'b)(xs:'acatlist):'bcatlist=fold((append),Empty)(fun(b:'a)->single(fb))xs//append ~ fun a acc -> append a acc
The filter function based on our fold function
1
2
3
4
5
6
letfilter(f:'a->bool)(xs:'acatlist):'acatlist=fold((fun(a:'acatlist)(acc:'acatlist)->appendaacc),Empty)(fun(b:'a)->iffbthensinglebelseEmpty)xs//append ~ fun a acc -> append a acc
Beware: our append function automatically filters “Empty” ‘a catlists out when calling append function!
moduleCatListopenDiffListtype'acatlist=|Empty|Singleof'a|Appendof'acatlist*'acatlistletnil:'acatlist=Emptyletsingle(elm:'a):'acatlist=Single(elm)letappend(c1:'acatlist)(c2:'acatlist):'acatlist=ifc1=Emptythenc2elseifc2=Emptythenc1elseAppend(c1,c2)letcons(elm:'a)(xs:'acatlist):'acatlist=append(singleelm)xsletsnoc(xs:'acatlist)(elm:'a):'acatlist=appendxs(singleelm)letfold(cf:('a->'a->'a)*'a)(f:'b->'a)(list:'bcatlist):'a=letrecg(xs:'bcatlist)=matchxswith|Empty->sndcf|Single(a:'b)->fa|Append(ys:'bcatlist,zs:'bcatlist)->fst(cf)(gys)(gzs)glistletlength(xs:'acatlist)=fold((+),0)(fun_->1)xsletmap(f:'a->'b)(xs:'acatlist):'bcatlist=fold((append),Empty)(fun(b:'a)->single(fb))xsletfilter(f:'a->bool)(xs:'acatlist):'acatlist=fold((fun(a:'acatlist)(acc:'acatlist)->appendaacc),Empty)(fun(b:'a)->iffbthensinglebelseEmpty)xsletrev(c:'acatlist):'acatlist=fold((fun(a:'acatlist)(acc:'acatlist)->appendacca),Empty)(fun(b:'a)->singleb)cletfromCatList(xs:'acatlist):'alist=fold((@),[])(funb->[b])xs//val fold:folder: ('State -> 'T -> 'State) -> state : 'State -> list : list<'T> -> 'Stateletinline(^@)selm=appends(singleelm)lettoCatList(xs:'alist):'acatlist=xs|>List.fold((^@))Emptyletitem(i:int)(xs:'acatlist):'a=if(i>=0)&&(i<lengthxs)thenfromCatList(xs).[i]elseraise(System.IndexOutOfRangeException("Du har valgt et index ude for størrelsen på catlisten!"))letinsert(i:int)(elm:'a)(xs:'acatlist):'acatlist=if(i>=0)&&(i<lengthxs)thenlett=fromCatListxsletf=t.[0..i-1]letf1=t.[i-1..t.Length]letnewList=f@[elm]@f1toCatListnewListelseraise(System.IndexOutOfRangeException("Du har valgt et index ude for størrelsen på catlisten!"))letdelete(i:int)(xs:'acatlist):'acatlist=if(i>=0)&&(i<lengthxs)thenlett=fromCatListxsletf=t.[0..i-2]letf1=t.[i..t.Length]toCatList(f@f1)elseraise(System.IndexOutOfRangeException("Du har valgt et index ude for størrelsen på catlisten!"))