diff --git a/tests/pos/eff-compose.scala b/tests/pos/eff-compose.scala new file mode 100644 index 000000000000..a1931bab47b6 --- /dev/null +++ b/tests/pos/eff-compose.scala @@ -0,0 +1,78 @@ +object Test { + + trait Effect + + // Type X => Y + abstract class Fun[-X, Y] { + type Eff <: Effect + def apply(x: X): implicit Eff => Y + } + + // Type X -> Y + type PureFun[-X, Y] = Fun[X, Y] { type Eff = Effect } + + // def map(f: A => B)(xs: List[A]): List[B] + def map[A, B, E <: Effect](f: Fun[A, B] { type Eff = E})(xs: List[A]) + : implicit E => List[B] = + xs.map(f.apply) + + // def mapFn[A, B]: (A => B) -> List[A] -> List[B] + def mapFn[A, B, E <: Effect]: + PureFun[ + Fun[A, B] { type Eff = E}, + Fun[List[A], List[B]] { type Eff = E } + ] = + new Fun[ // would like to write new PureFun here + // or, even better, drop everything + Fun[A, B] { type Eff = E}, + Fun[List[A], List[B]] { type Eff = E } + ] { + type Eff = Effect + def apply(f: Fun[A, B] { type Eff = E}) = + new Fun[List[A], List[B]] { + type Eff = E + def apply(xs: List[A]): implicit Eff => List[B] = + map(f)(xs) + } + } + + implicit def combine[E1 <: Effect, E2 <: Effect](implicit x: E1, y: E2): E1 & E2 = ??? + + // def compose(f: A => B)(g: B => C)(x: A): C + def compose[A, B, C, E1 <: Effect, E2 <: Effect] + (f: Fun[A, B] { type Eff = E1}) + (g: Fun[B, C] { type Eff = E2}) + (x: A): + implicit E1 & E2 => C = g(f(x)) + + // def composeFn: (A => B) -> (B => C) -> A -> C + def composeFn[A, B, C, E1 <: Effect, E2 <: Effect]: + PureFun[ + Fun[A, B] { type Eff = E1}, + PureFun[ + Fun[B, C] { type Eff = E2}, + Fun[A, C] { type Eff = E1 & E2 } + ] + ] = + new Fun[ + Fun[A, B] { type Eff = E1}, + PureFun[ + Fun[B, C] { type Eff = E2}, + Fun[A, C] { type Eff = E1 & E2 } + ] + ] { + type Eff = Effect + def apply(f: Fun[A, B] { type Eff = E1}) = + new Fun[ + Fun[B, C] { type Eff = E2}, + Fun[A, C] { type Eff = E1 & E2 } + ] { + type Eff = Effect + def apply(g: Fun[B, C] { type Eff = E2}) = + new Fun[A, C] { + type Eff = E1 & E2 + def apply(x: A) = compose(f)(g)(x) + } + } + } +} \ No newline at end of file diff --git a/tests/run/coop-equality.scala b/tests/run/coop-equality.scala new file mode 100644 index 000000000000..f32906cd8560 --- /dev/null +++ b/tests/run/coop-equality.scala @@ -0,0 +1,22 @@ +object Test extends App { + + class ANY { + def ===(that: ANY) = this eq that + } + + case class A(x: String) extends ANY { + def ===(that: A) = this.x == that.x + def ===(that: B) = this.x == that.x + } + + case class B(x: String) extends ANY { + def ===(that: A) = this.x == that.x + def ===(that: B) = this.x == that.x + } + + val a = A("") + val b = B("") + + assert(a === b) + assert(!((a: ANY) === (b: ANY))) +} \ No newline at end of file