From 76025cd33a64e3ff9d4257f3462fcbd261a9694d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 17 Aug 2016 17:23:20 +0200 Subject: Fix eta expansion for deeply curried methods Eta expansion yielded incorrect result if the eta expanded method has more than one parameter sections and the expected result type is a unary function type. In that case a postfix `_' needs to be appended. --- tests/pending/run/tcpoly_parseridioms.check | 21 ------ tests/pending/run/tcpoly_parseridioms.scala | 112 ---------------------------- 2 files changed, 133 deletions(-) delete mode 100644 tests/pending/run/tcpoly_parseridioms.check delete mode 100644 tests/pending/run/tcpoly_parseridioms.scala (limited to 'tests/pending') diff --git a/tests/pending/run/tcpoly_parseridioms.check b/tests/pending/run/tcpoly_parseridioms.check deleted file mode 100644 index 8bd0a086d..000000000 --- a/tests/pending/run/tcpoly_parseridioms.check +++ /dev/null @@ -1,21 +0,0 @@ -tcpoly_parseridioms.scala:18: warning: match may not be exhaustive. -It would fail on the following input: ParseResult() - case Success(next, x) => b(next) match { - ^ -tcpoly_parseridioms.scala:17: warning: match may not be exhaustive. -It would fail on the following input: ParseResult() - def apply(in: Input): ParseResult[Tuple2[T, U]] = a(in) match { - ^ -tcpoly_parseridioms.scala:30: warning: match may not be exhaustive. -It would fail on the following input: ParseResult() - case Failure(_, _) => b(in) match { - ^ -tcpoly_parseridioms.scala:28: warning: match may not be exhaustive. -It would fail on the following input: ParseResult() - def apply(in: Input): ParseResult[T] = a(in) match { - ^ -tcpoly_parseridioms.scala:39: warning: match may not be exhaustive. -It would fail on the following input: ParseResult() - def apply(in: Input): ParseResult[U] = a(in) match { - ^ -Success(List(),Plus(1,2)) diff --git a/tests/pending/run/tcpoly_parseridioms.scala b/tests/pending/run/tcpoly_parseridioms.scala deleted file mode 100644 index 6d541996c..000000000 --- a/tests/pending/run/tcpoly_parseridioms.scala +++ /dev/null @@ -1,112 +0,0 @@ - -import scala.language.{ higherKinds, implicitConversions, postfixOps } - -trait Parsers { - type Input = List[Char] - - sealed class ParseResult[+t](val next: Input) - case class Success[+t](override val next: Input, result: t) extends ParseResult[t](next) - case class Failure(override val next: Input, msg: String) extends ParseResult[Nothing](next) - - abstract class Parser[+t] { - def apply(in: Input): ParseResult[t] - } - - // sequence - def sq[T, U](a: => Parser[T], b: => Parser[U]): Parser[Tuple2[T, U]] = new Parser[Tuple2[T, U]] { - def apply(in: Input): ParseResult[Tuple2[T, U]] = a(in) match { - case Success(next, x) => b(next) match { - case Success(next2, y) => Success(next2, (x,y)) - case Failure(_, msg) => Failure(in, msg) - } - case Failure(_, msg) => Failure(in, msg) - } - } - - // ordered choice - def or[T, U <: T](a: => Parser[T], b: => Parser[U]): Parser[T] = new Parser[T] { - def apply(in: Input): ParseResult[T] = a(in) match { - case Success(next, x) => Success(next, x) - case Failure(_, _) => b(in) match { - case Success(next, y) => Success(next, y) - case Failure(_, msg) => Failure(in, msg) - } - } - } - - // lifting - def lift[T, U](f: T => U)(a: => Parser[T]): Parser[U] = new Parser[U] { - def apply(in: Input): ParseResult[U] = a(in) match { - case Success(n, x) => Success(n, f(x)) - case Failure(n, msg) => Failure(n, msg) - } - } - - def accept[T](c: Char, r: T): Parser[T] = new Parser[T] { - def apply(in: Input) = in match { - case c2 :: n if c2 == c => Success(n, r) - case n => Failure(n, "expected "+c+" at the head of "+n) - } - } - - def apply_++[s, tt](fun: Parser[s => tt], arg: Parser[s]): Parser[tt] = lift[Tuple2[s=>tt, s], tt]({case (f, a) => f(a)})(sq(fun, arg)) - - def success[u](v: u): Parser[u] = new Parser[u] { - def apply(in: Input) = Success(in, v) - } - -} - -trait Idioms { - trait Idiom[idi[x]] { - def liftedApply[s, t](fun: idi[s => t])(arg: idi[s]): idi[t] - def pure[a](x: a): idi[a] - def pureMethod[a](name: String, x: a): idi[a] = pure(x) // hack for Mirrors: allow passing of method names - } - - class IdiomaticTarget[idi[x], idiom <: Idiom[idi], s](i: idiom, tgt: s) { - def dot [t](fun: s => t, name: String) = new IdiomaticApp2[idi, idiom, t](i, i.liftedApply(i.pureMethod(name, fun))(i.pure(tgt))) - } // TODO: `.` --> java.lang.ClassFormatError: Illegal method name "." in class Idioms$Id$ - - class IdiomaticFunction[idi[x], idiom <: Idiom[idi], s, t](i: idiom, fun: s => t) { - def <| (a: idi[s]) = new IdiomaticApp[idi, idiom, t](i, i.liftedApply(i.pure(fun))(a)) - } - - class IdiomaticApp[idi[x], idiom <: Idiom[idi], x](i: idiom, a: idi[x]) { - // where x <: s=>t -- TODO can this be expressed without generalised constraints? - def <> [s, t](b: idi[s]) = new IdiomaticApp[idi, idiom, t](i, i.liftedApply(a.asInstanceOf[idi[s=>t]])(b)) - - def |> : idi[x] = a - } - - class IdiomaticApp2[idi[x], idiom <: Idiom[idi], x](i: idiom, a: idi[x]) extends IdiomaticApp[idi, idiom, x](i, a) { - def <| [s, t](b: idi[s]) = <>[s,t](b) - } -} - -trait ParserIdioms extends Parsers with Idioms { - object ParserIdiom extends Idiom[Parser] { - def liftedApply[s, t](fun: Parser[s => t])(arg: Parser[s]): Parser[t] = apply_++(fun, arg) - def pure[a](x: a): Parser[a] = success(x) - } - - implicit def parserIdiomFun[s, t](fun: s=>t): IdiomaticFunction[Parser, ParserIdiom.type, s, t] = - new IdiomaticFunction[Parser, ParserIdiom.type, s, t](ParserIdiom, fun) - implicit def parserIdiomTgt[s](tgt: s): IdiomaticTarget[Parser, ParserIdiom.type, s] = - new IdiomaticTarget[Parser, ParserIdiom.type, s](ParserIdiom, tgt) - - trait Expr - case class Plus(a: Int, b: Int) extends Expr - - def num = or(accept('0', 0), or(accept('1', 1),accept('2', 2))) - - // TODO: how can parserIdiom(curry2(_)) be omitted? - def expr: Parser[Expr] = parserIdiomFun(curry2(Plus)) <| num <> num |> - - implicit def curry2[s,t,u](fun: (s, t)=>u)(a: s)(b: t): u = fun(a, b) - implicit def curry3[r,s,t,u](fun: (r,s, t)=>u)(a: r)(b: s)(c: t): u = fun(a, b, c) -} - -object Test extends ParserIdioms with App { - println(expr("12".toList)) -} -- cgit v1.2.3