diff -r 8067d0a8ba04 -r 1b718d6065c2 progs/comb1.scala --- a/progs/comb1.scala Tue Jul 30 20:19:40 2019 +0100 +++ b/progs/comb1.scala Tue Jul 30 23:44:56 2019 +0100 @@ -1,11 +1,13 @@ import scala.language.implicitConversions import scala.language.reflectiveCalls -/* Note, in the lectures I did not show the implicit type consraint - * I => Seq[_], which means that the input type 'I' needs to be - * a sequence. */ +/* Note, in the lectures I did not show the implicit type + * constraint IsSeq, which means that the input type 'I' needs + * to be a sequence. */ -abstract class Parser[I, T](implicit ev: I => Seq[_]) { + type IsSeq[A] = A => Seq[_] + +abstract class Parser[I : IsSeq, T] { def parse(ts: I): Set[(T, I)] def parse_all(ts: I) : Set[T] = @@ -13,20 +15,20 @@ if (tail.isEmpty)) yield head } -class SeqParser[I, T, S](p: => Parser[I, T], - q: => Parser[I, S])(implicit ev: I => Seq[_]) extends Parser[I, (T, S)] { +class SeqParser[I : IsSeq, T, S](p: => Parser[I, T], + q: => Parser[I, S]) extends Parser[I, (T, S)] { def parse(sb: I) = for ((head1, tail1) <- p.parse(sb); (head2, tail2) <- q.parse(tail1)) yield ((head1, head2), tail2) } -class AltParser[I, T](p: => Parser[I, T], - q: => Parser[I, T])(implicit ev: I => Seq[_]) extends Parser[I, T] { +class AltParser[I : IsSeq, T](p: => Parser[I, T], + q: => Parser[I, T]) extends Parser[I, T] { def parse(sb: I) = p.parse(sb) ++ q.parse(sb) } -class FunParser[I, T, S](p: => Parser[I, T], - f: T => S)(implicit ev: I => Seq[_]) extends Parser[I, S] { +class FunParser[I : IsSeq, T, S](p: => Parser[I, T], + f: T => S) extends Parser[I, S] { def parse(sb: I) = for ((head, tail) <- p.parse(sb)) yield (f(head), tail) }