handouts/ho06.tex
changeset 941 66adcae6c762
parent 937 dc5ab66b11cc
--- a/handouts/ho06.tex	Thu Oct 05 14:36:54 2023 +0100
+++ b/handouts/ho06.tex	Fri Oct 13 15:07:37 2023 +0100
@@ -107,16 +107,20 @@
 class we specify that \texttt{I} is the \emph{input type} of the
 parser combinator and that \texttt{T} is the \emph{output type}.  This
 implies that the function \texttt{parse} takes an argument of type
-\texttt{I} and returns a set of type \mbox{\texttt{Set[(T, I)]}}.
+\texttt{I} and returns a set of type \mbox{\texttt{Set[(T,
+    I)]}}.\footnote{In the actual code on KEATS there is some
+  kerfuffle about correct type-bounds and using clauses. Ignore this
+  part of the implementation for the moment---it is not needed for
+  understanding how the code works.}
 
 \begin{center}
 \begin{lstlisting}[language=Scala]
-abstract class Parser[I, T](using is: I => Seq[_])  {
+abstract class Parser[I, T]  {
   def parse(in: I): Set[(T, I)]  
 
   def parse_all(in: I) : Set[T] =
     for ((hd, tl) <- parse(in); 
-        if is(tl).isEmpty) yield hd
+        if tl.isEmpty) yield hd
 }
 \end{lstlisting}
 \end{center}
@@ -214,8 +218,7 @@
 \begin{lstlisting}[language=Scala, numbers=none]
 class AltParser[I, T]
          (p: => Parser[I, T], 
-          q: => Parser[I, T])(using I => Seq[_])
-                                 extends Parser[I, T] {
+          q: => Parser[I, T]) extends Parser[I, T] {
   def parse(in: I) = p.parse(in) ++ q.parse(in)   
 }    
 \end{lstlisting}
@@ -306,8 +309,7 @@
 \begin{lstlisting}[language=Scala,numbers=none]
 class SeqParser[I, T, S]
        (p: => Parser[I, T], 
-        q: => Parser[I, S])(using I => Seq[_])
-                               extends Parser[I, (T, S)] {
+        q: => Parser[I, S]) extends Parser[I, (T, S)] {
   def parse(in: I) = 
     for ((output1, u1) <- p.parse(in); 
          (output2, u2) <- q.parse(u1)) 
@@ -483,7 +485,7 @@
 \begin{lstlisting}[language=Scala,basicstyle=\small\ttfamily, numbers=none]
 class MapParser[I, T, S]
         (p: => Parser[I, T], 
-         f: T => S)(using I => Seq[_]) extends Parser[I, S] {
+         f: T => S) extends Parser[I, S] {
   def parse(in: I) =
        for ((hd, tl) <- p.parse(in)) yield (f(hd), tl)
 }
@@ -593,7 +595,7 @@
 \texttt{Int}. Now \texttt{parse} generates \texttt{Set((123,abc))},
 but this time \texttt{123} is an \texttt{Int}. Think carefully what
 the input and output type of the parser is without the semantic action
-adn what with the semantic action (the type of the function can
+and what with the semantic action (the type of the function can
 already tell you). Let us come back to semantic actions when we are
 going to implement actual context-free grammars.