Skip to content

Instantly share code, notes, and snippets.

@sir-wabbit
Last active September 15, 2017 21:06
Show Gist options
  • Select an option

  • Save sir-wabbit/bdd0b43367fe480e3ef3e081339fbd19 to your computer and use it in GitHub Desktop.

Select an option

Save sir-wabbit/bdd0b43367fe480e3ef3e081339fbd19 to your computer and use it in GitHub Desktop.
import Abstract._
trait Abstract[A, T] {
type Result[_]
}
private[covenant] trait L4 {
implicit def otherwise[A, B]: Abstract.Aux[A, B, λ[X => B]] =
new Abstract.Aux1[A, B, λ[X => B]]
}
private[covenant] trait L3 extends L4 {
implicit def f1[A, F[_], B](implicit B: Abstract[A, B]): Abstract.Aux[A, F[B], λ[X => F[B.Result[X]]]] =
new Abstract.Aux1[A, F[B], λ[X => F[B.Result[X]]]]
}
private[covenant] trait L2 extends L3 {
implicit def f2[A, F[_, _], B1, B2](implicit B1: Abstract[A, B1] {}, B2: Abstract[A, B2] {}): Abstract.Aux[A, F[B1, B2], λ[X => F[B1.Result[X], B2.Result[X]]]] =
new Abstract.Aux1[A, F[B1, B2], λ[X => F[B1.Result[X], B2.Result[X]]]]
}
private[covenant] trait L1 extends L2 {
implicit def f3[A, F[_, _, _], B1, B2, B3](implicit B1: Abstract[A, B1] {}, B2: Abstract[A, B2] {}, B3: Abstract[A, B3] {}): Abstract.Aux[A, F[B1, B2, B3], λ[X => F[B1.Result[X], B2.Result[X], B3.Result[X]]]] =
new Abstract.Aux1[A, F[B1, B2, B3], λ[X => F[B1.Result[X], B2.Result[X], B3.Result[X]]]]
}
object Abstract extends L1 {
def apply[A, T](implicit T: Abstract[A, T] {}): Abstract.Aux[A, T, T.Result] = T
type Aux[T, A, F[_]] = Abstract[T, A] { type Result[X] = F[X] }
final class Aux1[T, A, F[_]] extends Abstract[T, A] { type Result[X] = F[X] }
implicit def id[A]: Abstract.Aux[A, A, λ[X => X]] =
new Aux1[A, A, λ[X => X]]
protected[this] type H
implicit def f1k[A, B[_], F[_[_]]](implicit B: Abstract2[A, H, B[H]]): Abstract.Aux[A, F[B], λ[X => F[B.Result[X, ?]]]] =
new Abstract.Aux1[A, F[B], λ[X => F[B.Result[X, ?]]]]
}
trait Abstract2[A, B, T] {
type Result[_, _]
}
private[covenant] trait Abstract2_4 {
implicit def otherwise[A, B, T]: Abstract2.Aux[A, B, T, λ[(X, Y) => T]] =
new Abstract2.Aux1[A, B, T, λ[(X, Y) => T]]
}
private[covenant] trait Abstract2_3 extends Abstract2_4 {
implicit def f1[A, B, F[_], I](implicit I: Abstract2[A, B, I]): Abstract2.Aux[A, B, F[I], λ[(X, Y) => F[I.Result[X, Y]]]] =
new Abstract2.Aux1[A, B, F[I], λ[(X, Y) => F[I.Result[X, Y]]]]
}
private[covenant] trait Abstract2_2 extends Abstract2_3 {
implicit def f2[A, B, F[_, _], I1, I2]
(implicit
I1: Abstract2[A, B, I1] {},
I2: Abstract2[A, B, I2] {}
): Abstract2.Aux[A, B, F[I1, I2], λ[(X, Y) => F[I1.Result[X, Y], I2.Result[X, Y]]]] =
new Abstract2.Aux1[A, B, F[I1, I2], λ[(X, Y) => F[I1.Result[X, Y], I2.Result[X, Y]]]]
}
private[covenant] trait Abstract2_1 extends Abstract2_2 {
implicit def f3[A, B, F[_, _, _], I1, I2, I3]
(implicit
I1: Abstract2[A, B, I1] {},
I2: Abstract2[A, B, I2] {},
I3: Abstract2[A, B, I3] {}
): Abstract2.Aux[A, B, F[I1, I2, I3], λ[(X, Y) => F[I1.Result[X, Y], I2.Result[X, Y], I3.Result[X, Y]]]] =
new Abstract2.Aux1[A, B, F[I1, I2, I3], λ[(X, Y) => F[I1.Result[X, Y], I2.Result[X, Y], I3.Result[X, Y]]]]
}
object Abstract2 extends Abstract2_1 {
def apply[A, B, T](implicit T: Abstract2[A, B, T] {}): Abstract2.Aux[A, B, T, T.Result] = T
type Aux[A, B, T, F[_, _]] = Abstract2[A, B, T] { type Result[X, Y] = F[X, Y] }
final class Aux1[A, B, T, F[_, _]] extends Abstract2[A, B, T] { type Result[X, Y] = F[X, Y] }
implicit def id1[A, B]: Abstract2.Aux[A, B, A, λ[(X, Y) => X]] =
new Aux1[A, B, A, λ[(X, Y) => X]]
implicit def id2[A, B]: Abstract2.Aux[A, B, B, λ[(X, Y) => Y]] =
new Aux1[A, B, B, λ[(X, Y) => Y]]
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
scala> Abstract[Int, Int]
res2: Abstract[Int, Int]{type Result[X] = X} = ...
scala> Abstract[Int, (Int, Option[Int])]
res0: Abstract[Int, (Int, Option[Int])]{type Result[X] = (X, Option[X])} = ...
scala> Abstract[Int, (Int, Option[Int], Long)]
res1: Abstract[Int,(Int, Option[Int], Long)]{type Result[X] = (X, Option[X], Long)} = ...
@arosien

arosien commented Sep 15, 2017

Copy link
Copy Markdown

uh, what is this??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment