From f96b6beefc08f56218ac68b37a4cecd757cb60ee Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 6 Apr 2007 09:39:53 +0000 Subject: adding test files from tcpoly branch without hi... adding test files from tcpoly branch without history -- much faster this way, sorry --- test/files/run/tcpoly_monads.check | 1 + test/files/run/tcpoly_monads.scala | 42 ++++++++++++ test/files/run/tcpoly_overriding.check | 1 + test/files/run/tcpoly_overriding.scala | 16 +++++ test/files/run/tcpoly_parseridioms.check | 1 + test/files/run/tcpoly_parseridioms.scala | 109 +++++++++++++++++++++++++++++++ 6 files changed, 170 insertions(+) create mode 100644 test/files/run/tcpoly_monads.check create mode 100644 test/files/run/tcpoly_monads.scala create mode 100644 test/files/run/tcpoly_overriding.check create mode 100644 test/files/run/tcpoly_overriding.scala create mode 100644 test/files/run/tcpoly_parseridioms.check create mode 100644 test/files/run/tcpoly_parseridioms.scala (limited to 'test/files/run') diff --git a/test/files/run/tcpoly_monads.check b/test/files/run/tcpoly_monads.check new file mode 100644 index 0000000000..d81cc0710e --- /dev/null +++ b/test/files/run/tcpoly_monads.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/tcpoly_monads.scala b/test/files/run/tcpoly_monads.scala new file mode 100644 index 0000000000..0ee160803a --- /dev/null +++ b/test/files/run/tcpoly_monads.scala @@ -0,0 +1,42 @@ +trait Monads { + /** + * class Monad m where + * (>>=) :: m a -> (a -> m b) -> m b + * return :: a -> m a + * + * MonadTC encodes the above Haskell type class, + * an instance of MonadTC corresponds to a method dictionary. + * (see http://lampwww.epfl.ch/~odersky/talks/wg2.8-boston06.pdf) + * + * Note that the identity (`this') of the method dictionary does not really correspond + * to the instance of m[x] (`self') that is `wrapped': e.g., unit does not use `self' (which + * corresponds to the argument of the implicit conversion that encodes an instance of this type class) + */ + trait MonadTC[m[x], a] { + def unit[a](orig: a): m[a] + + // >>='s first argument comes from the implicit definition constructing this "method dictionary" + def >>=[b](fun: a => m[b]): m[b] + } +} + +/** + * instance Monad Maybe where + * (Just x) >>= k = k x + * Nothing >>= _ = Nothing + */ +trait OptionMonad extends Monads { + // this implicit method encodes the Monad type class instance for Option + implicit def OptionInstOfMonad[a](self: Option[a]): MonadTC[Option, a] + = new MonadTC[Option, a] { + def unit[a](orig: a) = Some(orig) + def >>=[b](fun: a => Option[b]): Option[b] = self match { + case Some(x) => fun(x) + case None => None + } + } +} + +object Test extends OptionMonad with Application { + Console.println((Some("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") >>= (x => Some(x.length))).get) +} \ No newline at end of file diff --git a/test/files/run/tcpoly_overriding.check b/test/files/run/tcpoly_overriding.check new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/files/run/tcpoly_overriding.check @@ -0,0 +1 @@ +1 diff --git a/test/files/run/tcpoly_overriding.scala b/test/files/run/tcpoly_overriding.scala new file mode 100644 index 0000000000..970e16c71f --- /dev/null +++ b/test/files/run/tcpoly_overriding.scala @@ -0,0 +1,16 @@ +abstract class A[t[x]] { + def b: t[Int] +} + +class B extends A[List] { + // underlying functionality being tested is overriding, but bugs manifest itself during erasure + // erasure should generate two methods: one that returns an Object (to implement the method in A) + // one that is as close as possible to the original method and thus returns a List + // the problem only manifests itself here -- but it's really a problem with overriding + // the link between this method and the method in A isn't seen + def b: List[Int] = List(1) +} + +object Test extends Application { + Console.println((new B).b(0)) +} \ No newline at end of file diff --git a/test/files/run/tcpoly_parseridioms.check b/test/files/run/tcpoly_parseridioms.check new file mode 100644 index 0000000000..5fff2efb15 --- /dev/null +++ b/test/files/run/tcpoly_parseridioms.check @@ -0,0 +1 @@ +Success(List(),Plus(1,2)) diff --git a/test/files/run/tcpoly_parseridioms.scala b/test/files/run/tcpoly_parseridioms.scala new file mode 100644 index 0000000000..e163ea2ce8 --- /dev/null +++ b/test/files/run/tcpoly_parseridioms.scala @@ -0,0 +1,109 @@ +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[Pair[T, U]] = new Parser[Pair[T, U]] { + def apply(in: Input): ParseResult[Pair[T, U]] = a(in) match { + case Success(next, x) => b(next) match { + case Success(next2, y) => Success(next2, Pair(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[Pair[s=>tt, s], tt]({case Pair(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$IdiomaticTarget + + 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) = fun(a, b) + implicit def curry3[r,s,t,u](fun: (r,s, t)=>u)(a: r)(b: s)(c: t) = fun(a, b, c) +} + +object Test extends ParserIdioms with Application { + Console.println(expr(List.fromString("12"))) +} -- cgit v1.2.3