


% Taken from Alan Jeffrey's article ``Lists in TeX's mouth'',
% TUGboat 11(2), June 1990, http://tex.loria.fr/packages/lambda.dvi.


\def\Identity#1{#1}
\def\Error{\errmessage{Abandon verification all ye who enter here}}

\long\def\True#1#2{#1}
\long\def\False#1#2{#2}

\def\Compose#1#2#3{#1{#2{#3}}}
\def\Twiddle#1#2#3{#1{#3}{#2}}

\def\And#1#2{#1{#2}\False}
\def\Or#1#2{#1\True{#2}}

\def\Lift#1#2#3#4{#1{#4}{#2}{#3}{#4}}

\def\Lessthan#1#2{\TeXif{\ifnum#1<#2 }}
\def\Equalto#1#2{\TeXif{\ifnum#1=#2 }}


\def\TeXif#1#2#3{#1#2\else#3\fi}
\def\gobblefalse\else\gobbletrue\fi#1#2{\fi#1}
\def\gobbletrue\fi#1#2{\fi#2}
\def\TeXif#1{#1\gobblefalse\else\gobbletrue\fi}

\def\First#1#2{#1}
\def\Second#1#2{#2}

\let\Nil=\Second
\def\Cons#1#2#3#4{#3{#1}{#2}}
\def\Stream#1{\Cons{#1}{\Stream{#1}}}
\def\Singleton#1{\Cons{#1}\Nil}
\def\Head#1{#1\First\Error}
\def\Tail#1{#1\Second\Error}

\def\Foldl#1#2#3{#3{\Foldl@{#1}{#2}}{#2}}
\def\Foldl@#1#2#3#4{\Foldl{#1}{#1{#2}{#3}}{#4}}
\def\Foldr#1#2#3{#3{\Foldr@{#1}{#2}}{#2}}
\def\Foldr@#1#2#3#4{#1{#3}{\Foldr{#1}{#2}{#4}}}

\def\Cat#1#2{\Foldr\Cons{#2}{#1}}
\def\Reverse{\Foldl{\Twiddle\Cons}\Nil}

\def\All#1{\Foldr{\Compose\And{#1}}\True}
\def\Some#1{\Foldr{\Compose\Or{#1}}\False}
\def\Isempty{\All{\First\False}}

\def\Filter#1{\Foldr{\Lift{#1}\Cons\Second}\Nil}
\def\Map#1{\Foldr{\Compose\Cons{#1}}\Nil}

%\IsMem : int -> int list -> bool
\def\IsMem#1#2{\Some{\Equalto{#1}}{#2}}

\def\Insert#1#2#3{#3{\Insert@{#1}{#2}}{\Singleton{#2}}}
\def\Insert@#1#2#3#4{#1{#2}{#3}%
  {\Cons{#2}{\Cons{#3}{#4}}}%
  {\Cons{#3}{\Insert{#1}{#2}{#4}}}}
\def\Insertsort#1{\Foldr{\Insert{#1}}\Nil}

\def\Number#1{\csname Number�#1\endcsname}
\def\Label#1{\csname Label�#1\endcsname}

\def\Forward#1%
{\global\advance\Lastnum by 1\relax
\csnameafter\xdef{Number�#1}%
{\the\Lastnum}%
\csnameafter\xdef{Label�\the\Lastnum}%
{\@currentlabel}}

\def\csnameafter#1#2%
{\expandafter#1\csname#2\endcsname}

\def\Unlistize#1{[#1\Unlistize@{}]}
\def\Unlistize@#1{#1\Foldr\Commaize{}}
\def\Commaize#1#2{, #1#2}


\def\Listize[#1]%
{\Listize@#1,\relax]}
\def\Listize@#1,#2]%
{\TeXif{\ifx\relax#2}%
{\Singleton{#1}}%
{\Cons{#1}{\Listize@#2]}}}
%This only works for nonempty lists --- \Listize[]
%produces the singleton list \Singleton{}. It also
%uses \relax as its end�of�list character, so lists with
%\relax in them have to be done by hand.

\def\Show#1[#2]%
{\Unlistize{#1{\Listize[#2]}}}

\def\Bylist#1%
{\Map\Label
{\Insertsort\Lessthan
{\Map\Number{#1}}}}

\def\By{\Show\Bylist}

%So \By[Fac�yawn,Fac�cows] is [i, iii]. Which is
%quite nice.
